diff --git a/.gitignore b/.gitignore index d953f0a..905a774 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,4 @@ redhat-authentication.cdix tests/**/output test-resources test-results - +src/rh-api/gen diff --git a/package.json b/package.json index 767c7f8..4434308 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,9 @@ } }, "scripts": { - "build": "vite build && node ./scripts/build.cjs", + "generate:registry-authorizer": "npx openapi-typescript src/rh-api/registry-authorizer-schema.json -o src/rh-api/gen/registry-authorizer.d.ts", + "generate:subscription": "npx openapi-typescript src/rh-api/subscription-schema.json -o src/rh-api/gen/subscription.d.ts", + "build": "pnpm generate:subscription && pnpm generate:registry-authorizer && vite build && node ./scripts/build.cjs", "watch": "vite build -w", "format:check": "prettier --end-of-line auto --cache --check \"{src,types,scripts}/**/*.{ts,js}\"", "format:fix": "prettier --cache --write \"{src,types,scripts}/**/*.{ts,js}\"", @@ -49,11 +51,9 @@ "dependencies": { "@podman-desktop/api": "^1.14.1", "@podman-desktop/podman-extension-api": "^1.14.2", - "@redhat-developer/rhcra-client": "^0.0.1", - "@redhat-developer/rhsm-client": "^0.0.4", - "axios": "^1.8.2", "js-yaml": "^4.1.0", "object-hash": "3.0.0", + "openapi-fetch": "^0.13.4", "openid-client": "^5.7.0" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c721542..d380486 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,21 +14,15 @@ importers: '@podman-desktop/podman-extension-api': specifier: ^1.14.2 version: 1.14.2 - '@redhat-developer/rhcra-client': - specifier: ^0.0.1 - version: 0.0.1 - '@redhat-developer/rhsm-client': - specifier: ^0.0.4 - version: 0.0.4 - axios: - specifier: ^1.8.2 - version: 1.8.2 js-yaml: specifier: ^4.1.0 version: 4.1.0 object-hash: specifier: 3.0.0 version: 3.0.0 + openapi-fetch: + specifier: ^0.13.4 + version: 0.13.4 openid-client: specifier: ^5.7.0 version: 5.7.0 @@ -41,13 +35,13 @@ importers: version: 1.51.0 '@podman-desktop/tests-playwright': specifier: next - version: 1.18.0-202503112040-2d6bf64c221 + version: 1.18.0-202503141710-9bbff86da2a '@types/js-yaml': specifier: ^4.0.5 version: 4.0.9 '@types/node': specifier: ^20 - version: 20.17.24 + version: 20.17.21 '@typescript-eslint/eslint-plugin': specifier: ^8.26.1 version: 8.26.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2) @@ -56,7 +50,7 @@ importers: version: 6.21.0(eslint@8.57.1)(typescript@5.8.2) '@vitest/coverage-v8': specifier: ^2.0.5 - version: 2.0.5(vitest@2.0.5(@types/node@20.17.24)(terser@5.36.0)) + version: 2.0.5(vitest@2.0.5(@types/node@20.17.21)(terser@5.36.0)) byline: specifier: ^5.0.0 version: 5.0.0 @@ -74,10 +68,10 @@ importers: version: 8.57.1 eslint-import-resolver-custom-alias: specifier: ^1.3.2 - version: 1.3.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.5)(eslint@8.57.1)) + version: 1.3.2(eslint-plugin-import@2.31.0) eslint-import-resolver-typescript: specifier: ^3.8.5 - version: 3.8.5(eslint-plugin-import@2.31.0)(eslint@8.57.1) + version: 3.8.6(eslint-plugin-import@2.31.0)(eslint@8.57.1) eslint-plugin-etc: specifier: ^2.0.3 version: 2.0.3(eslint@8.57.1)(typescript@5.8.2) @@ -86,7 +80,7 @@ importers: version: 3.1.1(eslint@8.57.1) eslint-plugin-import: specifier: ^2.31.0 - version: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.5)(eslint@8.57.1) + version: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.6)(eslint@8.57.1) eslint-plugin-no-null: specifier: ^1.0.2 version: 1.0.2(eslint@8.57.1) @@ -116,10 +110,10 @@ importers: version: 5.8.2 vite: specifier: ^6.2.1 - version: 6.2.1(@types/node@20.17.24)(terser@5.36.0) + version: 6.2.1(@types/node@20.17.21)(terser@5.36.0) vitest: specifier: ^2.0.5 - version: 2.0.5(@types/node@20.17.24)(terser@5.36.0) + version: 2.0.5(@types/node@20.17.21)(terser@5.36.0) xvfb-maybe: specifier: ^0.2.1 version: 0.2.1 @@ -572,107 +566,101 @@ packages: '@podman-desktop/podman-extension-api@1.14.2': resolution: {integrity: sha512-KDLzvZP8/0BUR7IPYuv3NevsPWp9py2bScnYRU09OK5hbYmRCGKe9Y0Ni88Ihdg/GAbh0u8iWJcAbpgHEXoE+Q==} - '@podman-desktop/tests-playwright@1.18.0-202503112040-2d6bf64c221': - resolution: {integrity: sha512-Ynco0CaQDZ29N5+Ah0LHecGdyB1qhlYLj3R9eekoSMZ63FErFgsx3IzMEasNOC0S0dJEChU5V1Md9WQ6mz8frw==} + '@podman-desktop/tests-playwright@1.18.0-202503141710-9bbff86da2a': + resolution: {integrity: sha512-JPqRVg7Kfl1YkzS/vhRfecCtu4sdCHH2pKFaleR5jc2LI14acnovP/lHHBnKLtmNDIhT2iAyj57bV32jj+divw==} - '@redhat-developer/rhcra-client@0.0.1': - resolution: {integrity: sha512-Ltz1+LRistGEfvYP9mjmZcg9rn8YXdmg0YoNo2g8XeP4QvQ0E5Gv31+QTd7cw4w8sYc9ZVKCDH9cAFcMjMC5GA==} - - '@redhat-developer/rhsm-client@0.0.4': - resolution: {integrity: sha512-93Onlfg6z7WRffxPM2IcRaFZ8FEv0QeF2LBYaD7WY5hk4IZRoVBeqzUaT4Zd7hQ3Jw16wtuxoQfYUds7MBVOiQ==} - - '@rollup/rollup-android-arm-eabi@4.34.9': - resolution: {integrity: sha512-qZdlImWXur0CFakn2BJ2znJOdqYZKiedEPEVNTBrpfPjc/YuTGcaYZcdmNFTkUj3DU0ZM/AElcM8Ybww3xVLzA==} + '@rollup/rollup-android-arm-eabi@4.34.8': + resolution: {integrity: sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.34.9': - resolution: {integrity: sha512-4KW7P53h6HtJf5Y608T1ISKvNIYLWRKMvfnG0c44M6In4DQVU58HZFEVhWINDZKp7FZps98G3gxwC1sb0wXUUg==} + '@rollup/rollup-android-arm64@4.34.8': + resolution: {integrity: sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.34.9': - resolution: {integrity: sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ==} + '@rollup/rollup-darwin-arm64@4.34.8': + resolution: {integrity: sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.34.9': - resolution: {integrity: sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q==} + '@rollup/rollup-darwin-x64@4.34.8': + resolution: {integrity: sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.34.9': - resolution: {integrity: sha512-2lzjQPJbN5UnHm7bHIUKFMulGTQwdvOkouJDpPysJS+QFBGDJqcfh+CxxtG23Ik/9tEvnebQiylYoazFMAgrYw==} + '@rollup/rollup-freebsd-arm64@4.34.8': + resolution: {integrity: sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.34.9': - resolution: {integrity: sha512-SLl0hi2Ah2H7xQYd6Qaiu01kFPzQ+hqvdYSoOtHYg/zCIFs6t8sV95kaoqjzjFwuYQLtOI0RZre/Ke0nPaQV+g==} + '@rollup/rollup-freebsd-x64@4.34.8': + resolution: {integrity: sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.34.9': - resolution: {integrity: sha512-88I+D3TeKItrw+Y/2ud4Tw0+3CxQ2kLgu3QvrogZ0OfkmX/DEppehus7L3TS2Q4lpB+hYyxhkQiYPJ6Mf5/dPg==} + '@rollup/rollup-linux-arm-gnueabihf@4.34.8': + resolution: {integrity: sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.34.9': - resolution: {integrity: sha512-3qyfWljSFHi9zH0KgtEPG4cBXHDFhwD8kwg6xLfHQ0IWuH9crp005GfoUUh/6w9/FWGBwEHg3lxK1iHRN1MFlA==} + '@rollup/rollup-linux-arm-musleabihf@4.34.8': + resolution: {integrity: sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.34.9': - resolution: {integrity: sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw==} + '@rollup/rollup-linux-arm64-gnu@4.34.8': + resolution: {integrity: sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.34.9': - resolution: {integrity: sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A==} + '@rollup/rollup-linux-arm64-musl@4.34.8': + resolution: {integrity: sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.34.9': - resolution: {integrity: sha512-dRAgTfDsn0TE0HI6cmo13hemKpVHOEyeciGtvlBTkpx/F65kTvShtY/EVyZEIfxFkV5JJTuQ9tP5HGBS0hfxIg==} + '@rollup/rollup-linux-loongarch64-gnu@4.34.8': + resolution: {integrity: sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.34.9': - resolution: {integrity: sha512-PHcNOAEhkoMSQtMf+rJofwisZqaU8iQ8EaSps58f5HYll9EAY5BSErCZ8qBDMVbq88h4UxaNPlbrKqfWP8RfJA==} + '@rollup/rollup-linux-powerpc64le-gnu@4.34.8': + resolution: {integrity: sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.34.9': - resolution: {integrity: sha512-Z2i0Uy5G96KBYKjeQFKbbsB54xFOL5/y1P5wNBsbXB8yE+At3oh0DVMjQVzCJRJSfReiB2tX8T6HUFZ2k8iaKg==} + '@rollup/rollup-linux-riscv64-gnu@4.34.8': + resolution: {integrity: sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.34.9': - resolution: {integrity: sha512-U+5SwTMoeYXoDzJX5dhDTxRltSrIax8KWwfaaYcynuJw8mT33W7oOgz0a+AaXtGuvhzTr2tVKh5UO8GVANTxyQ==} + '@rollup/rollup-linux-s390x-gnu@4.34.8': + resolution: {integrity: sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.34.9': - resolution: {integrity: sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A==} + '@rollup/rollup-linux-x64-gnu@4.34.8': + resolution: {integrity: sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.34.9': - resolution: {integrity: sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA==} + '@rollup/rollup-linux-x64-musl@4.34.8': + resolution: {integrity: sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.34.9': - resolution: {integrity: sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q==} + '@rollup/rollup-win32-arm64-msvc@4.34.8': + resolution: {integrity: sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.34.9': - resolution: {integrity: sha512-KB48mPtaoHy1AwDNkAJfHXvHp24H0ryZog28spEs0V48l3H1fr4i37tiyHsgKZJnCmvxsbATdZGBpbmxTE3a9w==} + '@rollup/rollup-win32-ia32-msvc@4.34.8': + resolution: {integrity: sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.34.9': - resolution: {integrity: sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw==} + '@rollup/rollup-win32-x64-msvc@4.34.8': + resolution: {integrity: sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==} cpu: [x64] os: [win32] @@ -708,8 +696,8 @@ packages: '@types/keyv@3.1.4': resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} - '@types/node@20.17.24': - resolution: {integrity: sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA==} + '@types/node@20.17.21': + resolution: {integrity: sha512-yw1WZ94lZpdZbpnaF+WRvlN/Sx2EZWe/YZVdK4mC4u02/ql6Ozen8qbRJhOtltOxCg97/kpijhGs5X6STwkvbg==} '@types/node@22.13.10': resolution: {integrity: sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==} @@ -878,8 +866,8 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - acorn@8.14.1: - resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} engines: {node: '>=0.4.0'} hasBin: true @@ -956,16 +944,10 @@ packages: async@1.5.2: resolution: {integrity: sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==} - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axios@1.8.2: - resolution: {integrity: sha512-ls4GYBm5aig9vWx8AWDSGLpnpDQRtWAfrjU+EuytuODrFBkqesN2RkOQCBzrA1RQNHw1SmRMSDDDSwzNAYQ6Rg==} - balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1078,10 +1060,6 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -1188,10 +1166,6 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - detect-node@2.1.0: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} @@ -1328,8 +1302,8 @@ packages: eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} - eslint-import-resolver-typescript@3.8.5: - resolution: {integrity: sha512-0ZRnzOqKc7TRm85w6REOUkVLHevN6nWd/xZsmKhSD/dcDktoxQaQAg59e5EK/QEsGFf7o5JSpE6qTwCEz0WjTw==} + eslint-import-resolver-typescript@3.8.6: + resolution: {integrity: sha512-d9UjvYpj/REmUoZvOtDEmayPlwyP4zOwwMBgtC6RtrpZta8u1AIVmxgZBYJIcCKKXwAcLs+DX2yn2LeMaTqKcQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -1524,15 +1498,6 @@ packages: flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} - follow-redirects@1.15.9: - resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} @@ -1544,14 +1509,6 @@ packages: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - - form-data@4.0.2: - resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} - engines: {node: '>= 6'} - fs-extra@8.1.0: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} @@ -2074,14 +2031,6 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - mimic-fn@4.0.0: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} @@ -2135,8 +2084,8 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - nanoid@3.3.9: - resolution: {integrity: sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg==} + nanoid@3.3.8: + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -2211,6 +2160,12 @@ packages: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} + openapi-fetch@0.13.4: + resolution: {integrity: sha512-JHX7UYjLEiHuQGCPxa3CCCIqe/nc4bTIF9c4UYVC8BegAbWoS3g4gJxKX5XcG7UtYQs2060kY6DH64KkvNZahg==} + + openapi-typescript-helpers@0.0.15: + resolution: {integrity: sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw==} + openid-client@5.7.0: resolution: {integrity: sha512-4GCCGZt1i2kTHpwvaC/sCpTpQqDnBzDzuJcJMbH+y1Q5qI8U8RBvoSh28svarXszZHR5BAMXbJPX1PGPRE3VOA==} @@ -2350,9 +2305,6 @@ packages: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - pump@3.0.2: resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} @@ -2455,8 +2407,8 @@ packages: resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} engines: {node: '>=8.0'} - rollup@4.34.9: - resolution: {integrity: sha512-nF5XYqWWp9hx/LrpC8sZvvvmq0TeTjQgaZHYmAgwysT9nh8sWnZhBnM8ZyVbbJFIQBLwHDNoMqsBZBbUo4U8sQ==} + rollup@4.34.8: + resolution: {integrity: sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -3353,77 +3305,63 @@ snapshots: dependencies: '@podman-desktop/api': 1.14.2 - '@podman-desktop/tests-playwright@1.18.0-202503112040-2d6bf64c221': {} - - '@redhat-developer/rhcra-client@0.0.1': - dependencies: - axios: 1.8.2 - form-data: 4.0.0 - transitivePeerDependencies: - - debug - - '@redhat-developer/rhsm-client@0.0.4': - dependencies: - axios: 1.8.2 - form-data: 4.0.0 - transitivePeerDependencies: - - debug + '@podman-desktop/tests-playwright@1.18.0-202503141710-9bbff86da2a': {} - '@rollup/rollup-android-arm-eabi@4.34.9': + '@rollup/rollup-android-arm-eabi@4.34.8': optional: true - '@rollup/rollup-android-arm64@4.34.9': + '@rollup/rollup-android-arm64@4.34.8': optional: true - '@rollup/rollup-darwin-arm64@4.34.9': + '@rollup/rollup-darwin-arm64@4.34.8': optional: true - '@rollup/rollup-darwin-x64@4.34.9': + '@rollup/rollup-darwin-x64@4.34.8': optional: true - '@rollup/rollup-freebsd-arm64@4.34.9': + '@rollup/rollup-freebsd-arm64@4.34.8': optional: true - '@rollup/rollup-freebsd-x64@4.34.9': + '@rollup/rollup-freebsd-x64@4.34.8': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.34.9': + '@rollup/rollup-linux-arm-gnueabihf@4.34.8': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.34.9': + '@rollup/rollup-linux-arm-musleabihf@4.34.8': optional: true - '@rollup/rollup-linux-arm64-gnu@4.34.9': + '@rollup/rollup-linux-arm64-gnu@4.34.8': optional: true - '@rollup/rollup-linux-arm64-musl@4.34.9': + '@rollup/rollup-linux-arm64-musl@4.34.8': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.34.9': + '@rollup/rollup-linux-loongarch64-gnu@4.34.8': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.34.9': + '@rollup/rollup-linux-powerpc64le-gnu@4.34.8': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.34.9': + '@rollup/rollup-linux-riscv64-gnu@4.34.8': optional: true - '@rollup/rollup-linux-s390x-gnu@4.34.9': + '@rollup/rollup-linux-s390x-gnu@4.34.8': optional: true - '@rollup/rollup-linux-x64-gnu@4.34.9': + '@rollup/rollup-linux-x64-gnu@4.34.8': optional: true - '@rollup/rollup-linux-x64-musl@4.34.9': + '@rollup/rollup-linux-x64-musl@4.34.8': optional: true - '@rollup/rollup-win32-arm64-msvc@4.34.9': + '@rollup/rollup-win32-arm64-msvc@4.34.8': optional: true - '@rollup/rollup-win32-ia32-msvc@4.34.9': + '@rollup/rollup-win32-ia32-msvc@4.34.8': optional: true - '@rollup/rollup-win32-x64-msvc@4.34.9': + '@rollup/rollup-win32-x64-msvc@4.34.8': optional: true '@rtsao/scc@1.1.0': {} @@ -3438,7 +3376,7 @@ snapshots: dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 20.17.24 + '@types/node': 20.17.21 '@types/responselike': 1.0.3 '@types/estree@1.0.6': {} @@ -3453,9 +3391,9 @@ snapshots: '@types/keyv@3.1.4': dependencies: - '@types/node': 20.17.24 + '@types/node': 20.17.21 - '@types/node@20.17.24': + '@types/node@20.17.21': dependencies: undici-types: 6.19.8 @@ -3467,7 +3405,7 @@ snapshots: '@types/responselike@1.0.3': dependencies: - '@types/node': 20.17.24 + '@types/node': 20.17.21 '@types/semver@7.5.8': {} @@ -3479,7 +3417,7 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 20.17.24 + '@types/node': 20.17.21 optional: true '@typescript-eslint/eslint-plugin@8.26.1(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1)(typescript@5.8.2)': @@ -3652,7 +3590,7 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@vitest/coverage-v8@2.0.5(vitest@2.0.5(@types/node@20.17.24)(terser@5.36.0))': + '@vitest/coverage-v8@2.0.5(vitest@2.0.5(@types/node@20.17.21)(terser@5.36.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 @@ -3666,7 +3604,7 @@ snapshots: std-env: 3.7.0 test-exclude: 7.0.1 tinyrainbow: 1.2.0 - vitest: 2.0.5(@types/node@20.17.24)(terser@5.36.0) + vitest: 2.0.5(@types/node@20.17.21)(terser@5.36.0) transitivePeerDependencies: - supports-color @@ -3709,7 +3647,7 @@ snapshots: acorn@8.12.1: {} - acorn@8.14.1: + acorn@8.14.0: optional: true ajv@6.12.6: @@ -3809,20 +3747,10 @@ snapshots: async@1.5.2: {} - asynckit@0.4.0: {} - available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.0.0 - axios@1.8.2: - dependencies: - follow-redirects: 1.15.9 - form-data: 4.0.2 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - balanced-match@1.0.2: {} boolean@3.2.0: @@ -3945,10 +3873,6 @@ snapshots: color-name@1.1.4: {} - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - commander@2.20.3: optional: true @@ -4054,8 +3978,6 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 - delayed-stream@1.0.0: {} - detect-node@2.1.0: optional: true @@ -4327,9 +4249,9 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-custom-alias@1.3.2(eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.5)(eslint@8.57.1)): + eslint-import-resolver-custom-alias@1.3.2(eslint-plugin-import@2.31.0): dependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.5)(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.6)(eslint@8.57.1) glob-parent: 6.0.2 resolve: 1.22.8 @@ -4341,7 +4263,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.8.5(eslint-plugin-import@2.31.0)(eslint@8.57.1): + eslint-import-resolver-typescript@3.8.6(eslint-plugin-import@2.31.0)(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.0 @@ -4352,18 +4274,18 @@ snapshots: stable-hash: 0.0.4 tinyglobby: 0.2.12 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.5)(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.6)(eslint@8.57.1) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.5(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.6)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.8.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.8.5(eslint-plugin-import@2.31.0)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.8.6(eslint-plugin-import@2.31.0)(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -4384,7 +4306,7 @@ snapshots: dependencies: eslint: 8.57.1 - eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.5)(eslint@8.57.1): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.8.6)(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -4395,7 +4317,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.5(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.6)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -4626,8 +4548,6 @@ snapshots: flatted@3.3.1: {} - follow-redirects@1.15.9: {} - for-each@0.3.3: dependencies: is-callable: 1.2.7 @@ -4641,19 +4561,6 @@ snapshots: cross-spawn: 7.0.3 signal-exit: 4.1.0 - form-data@4.0.0: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - - form-data@4.0.2: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - es-set-tostringtag: 2.1.0 - mime-types: 2.1.35 - fs-extra@8.1.0: dependencies: graceful-fs: 4.2.11 @@ -5207,12 +5114,6 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - mimic-fn@4.0.0: {} mimic-response@1.0.1: {} @@ -5247,7 +5148,7 @@ snapshots: ms@2.1.3: {} - nanoid@3.3.9: {} + nanoid@3.3.8: {} natural-compare@1.4.0: {} @@ -5326,6 +5227,12 @@ snapshots: dependencies: mimic-fn: 4.0.0 + openapi-fetch@0.13.4: + dependencies: + openapi-typescript-helpers: 0.0.15 + + openapi-typescript-helpers@0.0.15: {} + openid-client@5.7.0: dependencies: jose: 4.15.9 @@ -5428,7 +5335,7 @@ snapshots: postcss@8.5.3: dependencies: - nanoid: 3.3.9 + nanoid: 3.3.8 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -5440,8 +5347,6 @@ snapshots: progress@2.0.3: {} - proxy-from-env@1.1.0: {} - pump@3.0.2: dependencies: end-of-stream: 1.4.4 @@ -5563,29 +5468,29 @@ snapshots: sprintf-js: 1.1.3 optional: true - rollup@4.34.9: + rollup@4.34.8: dependencies: '@types/estree': 1.0.6 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.34.9 - '@rollup/rollup-android-arm64': 4.34.9 - '@rollup/rollup-darwin-arm64': 4.34.9 - '@rollup/rollup-darwin-x64': 4.34.9 - '@rollup/rollup-freebsd-arm64': 4.34.9 - '@rollup/rollup-freebsd-x64': 4.34.9 - '@rollup/rollup-linux-arm-gnueabihf': 4.34.9 - '@rollup/rollup-linux-arm-musleabihf': 4.34.9 - '@rollup/rollup-linux-arm64-gnu': 4.34.9 - '@rollup/rollup-linux-arm64-musl': 4.34.9 - '@rollup/rollup-linux-loongarch64-gnu': 4.34.9 - '@rollup/rollup-linux-powerpc64le-gnu': 4.34.9 - '@rollup/rollup-linux-riscv64-gnu': 4.34.9 - '@rollup/rollup-linux-s390x-gnu': 4.34.9 - '@rollup/rollup-linux-x64-gnu': 4.34.9 - '@rollup/rollup-linux-x64-musl': 4.34.9 - '@rollup/rollup-win32-arm64-msvc': 4.34.9 - '@rollup/rollup-win32-ia32-msvc': 4.34.9 - '@rollup/rollup-win32-x64-msvc': 4.34.9 + '@rollup/rollup-android-arm-eabi': 4.34.8 + '@rollup/rollup-android-arm64': 4.34.8 + '@rollup/rollup-darwin-arm64': 4.34.8 + '@rollup/rollup-darwin-x64': 4.34.8 + '@rollup/rollup-freebsd-arm64': 4.34.8 + '@rollup/rollup-freebsd-x64': 4.34.8 + '@rollup/rollup-linux-arm-gnueabihf': 4.34.8 + '@rollup/rollup-linux-arm-musleabihf': 4.34.8 + '@rollup/rollup-linux-arm64-gnu': 4.34.8 + '@rollup/rollup-linux-arm64-musl': 4.34.8 + '@rollup/rollup-linux-loongarch64-gnu': 4.34.8 + '@rollup/rollup-linux-powerpc64le-gnu': 4.34.8 + '@rollup/rollup-linux-riscv64-gnu': 4.34.8 + '@rollup/rollup-linux-s390x-gnu': 4.34.8 + '@rollup/rollup-linux-x64-gnu': 4.34.8 + '@rollup/rollup-linux-x64-musl': 4.34.8 + '@rollup/rollup-win32-arm64-msvc': 4.34.8 + '@rollup/rollup-win32-ia32-msvc': 4.34.8 + '@rollup/rollup-win32-x64-msvc': 4.34.8 fsevents: 2.3.3 run-parallel@1.2.0: @@ -5842,7 +5747,7 @@ snapshots: terser@5.36.0: dependencies: '@jridgewell/source-map': 0.3.6 - acorn: 8.14.1 + acorn: 8.14.0 commander: 2.20.3 source-map-support: 0.5.21 optional: true @@ -6029,13 +5934,13 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - vite-node@2.0.5(@types/node@20.17.24)(terser@5.36.0): + vite-node@2.0.5(@types/node@20.17.21)(terser@5.36.0): dependencies: cac: 6.7.14 debug: 4.4.0 pathe: 1.1.2 tinyrainbow: 1.2.0 - vite: 5.4.14(@types/node@20.17.24)(terser@5.36.0) + vite: 5.4.14(@types/node@20.17.21)(terser@5.36.0) transitivePeerDependencies: - '@types/node' - less @@ -6047,27 +5952,27 @@ snapshots: - supports-color - terser - vite@5.4.14(@types/node@20.17.24)(terser@5.36.0): + vite@5.4.14(@types/node@20.17.21)(terser@5.36.0): dependencies: esbuild: 0.21.5 postcss: 8.5.3 - rollup: 4.34.9 + rollup: 4.34.8 optionalDependencies: - '@types/node': 20.17.24 + '@types/node': 20.17.21 fsevents: 2.3.3 terser: 5.36.0 - vite@6.2.1(@types/node@20.17.24)(terser@5.36.0): + vite@6.2.1(@types/node@20.17.21)(terser@5.36.0): dependencies: esbuild: 0.25.0 postcss: 8.5.3 - rollup: 4.34.9 + rollup: 4.34.8 optionalDependencies: - '@types/node': 20.17.24 + '@types/node': 20.17.21 fsevents: 2.3.3 terser: 5.36.0 - vitest@2.0.5(@types/node@20.17.24)(terser@5.36.0): + vitest@2.0.5(@types/node@20.17.21)(terser@5.36.0): dependencies: '@ampproject/remapping': 2.3.0 '@vitest/expect': 2.0.5 @@ -6085,11 +5990,11 @@ snapshots: tinybench: 2.9.0 tinypool: 1.0.1 tinyrainbow: 1.2.0 - vite: 5.4.14(@types/node@20.17.24)(terser@5.36.0) - vite-node: 2.0.5(@types/node@20.17.24)(terser@5.36.0) + vite: 5.4.14(@types/node@20.17.21)(terser@5.36.0) + vite-node: 2.0.5(@types/node@20.17.21)(terser@5.36.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 20.17.24 + '@types/node': 20.17.21 transitivePeerDependencies: - less - lightningcss diff --git a/src/extension.spec.ts b/src/extension.spec.ts index 142ba5b..318c930 100644 --- a/src/extension.spec.ts +++ b/src/extension.spec.ts @@ -20,12 +20,12 @@ import type { AuthenticationGetSessionOptions, AuthenticationSession, ExtensionContext } from '@podman-desktop/api'; import { authentication, commands } from '@podman-desktop/api'; -import { OrganizationService } from '@redhat-developer/rhsm-client'; import { afterEach, beforeEach, expect, suite, test, vi } from 'vitest'; import * as extension from './extension'; import * as podmanCli from './podman-cli'; -import * as subscription from './subscription'; +import { Organization } from './rh-api/subscription'; +import * as subscription from './rh-api/subscription'; import { ExtensionTelemetryLogger } from './telemetry'; import * as util from './util'; @@ -180,8 +180,18 @@ suite('signin command telemetry reports', () => { }, ); vi.spyOn(subscription, 'isRedHatRegistryConfigured').mockReturnValue(true); - vi.spyOn(podmanCli, 'getConnectionForRunningPodmanMachine').mockReturnValue('machine1'); - vi.spyOn(OrganizationService.prototype, 'checkOrgScaCapability').mockResolvedValue({ body: {} }); + vi.spyOn(podmanCli, 'getConnectionForRunningPodmanMachine').mockReturnValue({ + providerId: '1', + connection: { + name: 'machine1', + type: 'podman', + endpoint: { + socketPath: '/path/to/the/socket', + }, + status: () => 'started', + }, + }); + vi.spyOn(Organization.prototype, 'checkOrgScaCapability').mockResolvedValue({ body: {} }); await extension.activate(createExtContext()); expect(commandFunctionCopy!).toBeDefined(); await commandFunctionCopy!(); diff --git a/src/extension.ts b/src/extension.ts index 77bfb35..dc7882d 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -17,9 +17,6 @@ ***********************************************************************/ import * as extensionApi from '@podman-desktop/api'; -import type { ServiceAccountV1 } from '@redhat-developer/rhcra-client'; -import { ContainerRegistryAuthorizerClient } from '@redhat-developer/rhcra-client'; -import { SubscriptionManagerClient } from '@redhat-developer/rhsm-client'; import icon from '../icon.png'; import { onDidChangeSessions, RedHatAuthenticationService } from './authentication-service'; @@ -35,10 +32,11 @@ import { runSubscriptionManagerRegister, runSubscriptionManagerUnregister, } from './podman-cli'; +import { ContainerRegistryAuthorizerClient } from './rh-api/registry-authorizer'; +import { isRedHatRegistryConfigured, REGISTRY_REDHAT_IO, SubscriptionManagerClient } from './rh-api/subscription'; import { SSOStatusBarItem } from './status-bar-item'; -import { isRedHatRegistryConfigured, REGISTRY_REDHAT_IO, signIntoRedHatDeveloperAccount } from './subscription'; import { ExtensionTelemetryLogger as TelemetryLogger } from './telemetry'; -import { isLinux } from './util'; +import { isLinux, signIntoRedHatDeveloperAccount } from './util'; interface JwtToken { organization: { @@ -96,29 +94,32 @@ function removeRegistry(serverUrl: string = REGISTRY_REDHAT_IO): void { async function createOrReuseRegistryServiceAccount(): Promise { const currentSession = await signIntoRedHatDeveloperAccount(); const accessTokenJson = parseJwt(currentSession!.accessToken); - const client = new ContainerRegistryAuthorizerClient({ + const { serviceAccountsApiV1: saApiV1 } = new ContainerRegistryAuthorizerClient({ BASE: 'https://access.redhat.com/hydra/rest/terms-based-registry', TOKEN: currentSession!.accessToken, }); - const saApiV1 = client.serviceAccountsApiV1; - let selectedServiceAccount: ServiceAccountV1 | undefined; - try { - selectedServiceAccount = await saApiV1.serviceAccountByNameUsingGet1( - 'podman-desktop', - accessTokenJson.organization.id, - ); - } catch (err) { + let { data: serviceAccount } = await saApiV1.serviceAccountByNameUsingGet1( + 'podman-desktop', + accessTokenJson.organization.id, + ); + + if (!serviceAccount) { // ignore error when there is no podman-desktop service account yet - selectedServiceAccount = await saApiV1.createServiceAccountUsingPost1({ + const { data: createdServiceAccount } = await saApiV1.createServiceAccountUsingPost1({ name: 'podman-desktop', description: 'Service account to use from Podman Desktop', redHatAccountId: accessTokenJson.organization.id, }); + if (createdServiceAccount) { + serviceAccount = createdServiceAccount; + } else { + throw new Error(`Can't create registry authorizer service account.`); + } } await createRegistry( - selectedServiceAccount!.credentials!.username!, - selectedServiceAccount!.credentials!.password!, + serviceAccount!.credentials!.username!, + serviceAccount!.credentials!.password!, currentSession.account.label, ); } @@ -131,20 +132,20 @@ async function createOrReuseActivationKey(connection: extensionApi.ProviderConta TOKEN: currentSession!.accessToken, }); - try { - await client.activationKey.showActivationKey('podman-desktop'); - // podman-desktop activation key exists - } catch (err) { - // ignore and continue with activation key creation - // TODO: add check that used role and usage exists in organization - await client.activationKey.createActivationKeys({ + const { error: showKeyErr } = await client.activationKey.showActivationKey('podman-desktop'); + + if (showKeyErr) { + // error is undefined when activation key already exists + const { error: createKeyErr } = await client.activationKey.createActivationKeys({ name: 'podman-desktop', role: 'RHEl Workstation', usage: 'Development/Test', serviceLevel: 'Self-Support', }); + if (createKeyErr) { + throw new Error(createKeyErr.error?.message); + } } - await runSubscriptionManagerRegister(connection, 'podman-desktop', accessTokenJson.organization.id); } @@ -154,8 +155,8 @@ async function isSimpleContentAccessEnabled(): Promise { BASE: 'https://console.redhat.com/api/rhsm/v2', TOKEN: currentSession!.accessToken, }); - const response = await client.organization.checkOrgScaCapability(); - return !!response.body && response.body.simpleContentAccess === 'enabled'; + const data = await client.organization.checkOrgScaCapability(); + return data?.body?.simpleContentAccess === 'enabled'; } async function isSubscriptionManagerInstalled(connection: extensionApi.ProviderContainerConnection): Promise { diff --git a/src/rh-api/registry-authorizer-schema.json b/src/rh-api/registry-authorizer-schema.json new file mode 100644 index 0000000..164d7a9 --- /dev/null +++ b/src/rh-api/registry-authorizer-schema.json @@ -0,0 +1,1207 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "Api Documentation", + "description": "Api Documentation", + "termsOfService": "urn:tos", + "contact": {}, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0" + }, + "version": "1.0" + }, + "servers": [ + { + "url": "//localhost:8443/" + } + ], + "tags": [ + { + "name": "admin-api-v-1", + "description": "Admin Api V 1" + }, + { + "name": "authorization-api-v-1", + "description": "Authorization Api V 1" + }, + { + "name": "export-hold-api-v-1", + "description": "Export Hold Api V 1" + }, + { + "name": "health-api-v-1", + "description": "Health Api V 1" + }, + { + "name": "partner-service-accounts-api-v-1", + "description": "Partner Service Accounts Api V 1" + }, + { + "name": "service-accounts-api-v-1", + "description": "Service Accounts Api V 1" + } + ], + "paths": { + "/v1/_admin/ensureDataIndexed": { + "post": { + "tags": [ + "admin-api-v-1" + ], + "summary": "ensureDataIndexed", + "operationId": "ensureDataIndexedUsingPOST", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/ResponseEntity" + } + } + } + }, + "201": { + "description": "Created", + "content": {} + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + }, + "404": { + "description": "Not Found", + "content": {} + } + }, + "deprecated": false + } + }, + "/v1/_admin/environment/{property}": { + "get": { + "tags": [ + "admin-api-v-1" + ], + "summary": "environment", + "operationId": "environmentUsingGET", + "parameters": [ + { + "name": "property", + "in": "path", + "description": "property", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": {} + } + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + }, + "404": { + "description": "Not Found", + "content": {} + } + }, + "deprecated": false + } + }, + "/v1/authorization": { + "post": { + "tags": [ + "authorization-api-v-1" + ], + "summary": "getAuthorization", + "operationId": "getAuthorizationUsingPOST", + "requestBody": { + "description": "request", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/GetAuthorizationV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/AuthorizationV1" + } + } + } + }, + "201": { + "description": "Created", + "content": {} + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + }, + "404": { + "description": "Not Found", + "content": {} + } + }, + "deprecated": false, + "x-codegen-request-body-name": "request" + } + }, + "/v1/diagnostics": { + "get": { + "tags": [ + "health-api-v-1" + ], + "summary": "diagnostics", + "operationId": "diagnosticsUsingGET", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/ServiceHealth" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + }, + "404": { + "description": "Not Found", + "content": {} + } + }, + "deprecated": false + } + }, + "/v1/export-holds": { + "post": { + "tags": [ + "export-hold-api-v-1" + ], + "summary": "setExportHold", + "operationId": "setExportHoldUsingPOST", + "requestBody": { + "description": "request", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/SetExportHoldV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/ExportHoldReviewV1" + } + } + } + }, + "201": { + "description": "Created", + "content": {} + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + }, + "404": { + "description": "Not Found", + "content": {} + } + }, + "deprecated": false, + "x-codegen-request-body-name": "request" + } + }, + "/v1/export-holds/{rhAccountId}": { + "get": { + "tags": [ + "export-hold-api-v-1" + ], + "summary": "exportHoldStatusForAccount", + "operationId": "exportHoldStatusForAccountUsingGET", + "parameters": [ + { + "name": "rhAccountId", + "in": "path", + "description": "rhAccountId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/ExportHoldReviewV1" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + }, + "404": { + "description": "Not Found", + "content": {} + } + }, + "deprecated": false + } + }, + "/v1/health": { + "get": { + "tags": [ + "health-api-v-1" + ], + "summary": "health", + "operationId": "healthUsingGET", + "parameters": [ + { + "name": "includeBody", + "in": "query", + "description": "includeBody", + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/ServiceHealth" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + }, + "404": { + "description": "Not Found", + "content": {} + } + }, + "deprecated": false + } + }, + "/v1/liveness": { + "get": { + "tags": [ + "health-api-v-1" + ], + "summary": "liveness", + "operationId": "livenessUsingGET", + "responses": { + "200": { + "description": "OK", + "content": {} + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + }, + "404": { + "description": "Not Found", + "content": {} + } + }, + "deprecated": false + } + }, + "/v1/partners/{partnerCode}/service-accounts": { + "post": { + "tags": [ + "partner-service-accounts-api-v-1" + ], + "summary": "createServiceAccount", + "operationId": "createServiceAccountUsingPOST", + "parameters": [ + { + "name": "partnerCode", + "in": "path", + "description": "partnerCode", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "request", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/CreatePartnerServiceAccountV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/PartnerServiceAccountV1" + } + } + } + }, + "201": { + "description": "Created", + "content": {} + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + }, + "404": { + "description": "Not Found", + "content": {} + } + }, + "deprecated": false, + "x-codegen-request-body-name": "request" + } + }, + "/v1/partners/{partnerCode}/service-accounts/{name}": { + "get": { + "tags": [ + "partner-service-accounts-api-v-1" + ], + "summary": "serviceAccountByName", + "operationId": "serviceAccountByNameUsingGET", + "parameters": [ + { + "name": "name", + "in": "path", + "description": "name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "partnerCode", + "in": "path", + "description": "partnerCode", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/PartnerServiceAccountV1" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + }, + "404": { + "description": "Not Found", + "content": {} + } + }, + "deprecated": false + }, + "post": { + "tags": [ + "partner-service-accounts-api-v-1" + ], + "summary": "updateServiceAccount", + "operationId": "updateServiceAccountUsingPOST", + "parameters": [ + { + "name": "name", + "in": "path", + "description": "name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "partnerCode", + "in": "path", + "description": "partnerCode", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "request", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/UpdateServiceAccountV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/PartnerServiceAccountV1" + } + } + } + }, + "201": { + "description": "Created", + "content": {} + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + }, + "404": { + "description": "Not Found", + "content": {} + } + }, + "deprecated": false, + "x-codegen-request-body-name": "request" + }, + "delete": { + "tags": [ + "partner-service-accounts-api-v-1" + ], + "summary": "deleteServiceAccount", + "operationId": "deleteServiceAccountUsingDELETE", + "parameters": [ + { + "name": "name", + "in": "path", + "description": "name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "partnerCode", + "in": "path", + "description": "partnerCode", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": {} + }, + "204": { + "description": "No Content", + "content": {} + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + } + }, + "deprecated": false + } + }, + "/v1/readiness": { + "get": { + "tags": [ + "health-api-v-1" + ], + "summary": "readiness", + "operationId": "readinessUsingGET", + "responses": { + "200": { + "description": "OK", + "content": {} + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + }, + "404": { + "description": "Not Found", + "content": {} + } + }, + "deprecated": false + } + }, + "/v1/service-accounts": { + "post": { + "tags": [ + "service-accounts-api-v-1" + ], + "summary": "createServiceAccount", + "operationId": "createServiceAccountUsingPOST_1", + "requestBody": { + "description": "request", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/CreateServiceAccountV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/ServiceAccountV1" + } + } + } + }, + "201": { + "description": "Created", + "content": {} + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + }, + "404": { + "description": "Not Found", + "content": {} + } + }, + "deprecated": false, + "x-codegen-request-body-name": "request" + } + }, + "/v1/service-accounts/token-signing-key": { + "get": { + "tags": [ + "service-accounts-api-v-1" + ], + "summary": "signingKey", + "operationId": "signingKeyUsingGET", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/KeyV1" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + }, + "404": { + "description": "Not Found", + "content": {} + } + }, + "deprecated": false + } + }, + "/v1/service-accounts/{rhAccountId}": { + "get": { + "tags": [ + "service-accounts-api-v-1" + ], + "summary": "listServicesForAccount", + "operationId": "listServicesForAccountUsingGET", + "parameters": [ + { + "name": "maxResults", + "in": "query", + "description": "maxResults", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "offset", + "in": "query", + "description": "offset", + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "rhAccountId", + "in": "path", + "description": "rhAccountId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/SummariesV1" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + }, + "404": { + "description": "Not Found", + "content": {} + } + }, + "deprecated": false + } + }, + "/v1/service-accounts/{rhAccountId}/{name}": { + "get": { + "tags": [ + "service-accounts-api-v-1" + ], + "summary": "serviceAccountByName", + "operationId": "serviceAccountByNameUsingGET_1", + "parameters": [ + { + "name": "name", + "in": "path", + "description": "name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "rhAccountId", + "in": "path", + "description": "rhAccountId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/ServiceAccountV1" + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + }, + "404": { + "description": "Not Found", + "content": {} + } + }, + "deprecated": false + }, + "post": { + "tags": [ + "service-accounts-api-v-1" + ], + "summary": "updateServiceAccount", + "operationId": "updateServiceAccountUsingPOST_1", + "parameters": [ + { + "name": "name", + "in": "path", + "description": "name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "rhAccountId", + "in": "path", + "description": "rhAccountId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "request", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/UpdateServiceAccountV1" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json;charset=UTF-8": { + "schema": { + "$ref": "#/components/schemas/ServiceAccountV1" + } + } + } + }, + "201": { + "description": "Created", + "content": {} + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + }, + "404": { + "description": "Not Found", + "content": {} + } + }, + "deprecated": false, + "x-codegen-request-body-name": "request" + }, + "delete": { + "tags": [ + "service-accounts-api-v-1" + ], + "summary": "deleteServiceAccount", + "operationId": "deleteServiceAccountUsingDELETE_1", + "parameters": [ + { + "name": "name", + "in": "path", + "description": "name", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "rhAccountId", + "in": "path", + "description": "rhAccountId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": {} + }, + "204": { + "description": "No Content", + "content": {} + }, + "401": { + "description": "Unauthorized", + "content": {} + }, + "403": { + "description": "Forbidden", + "content": {} + } + }, + "deprecated": false + } + } + }, + "components": { + "schemas": { + "AuthorizationV1": { + "title": "AuthorizationV1", + "type": "object", + "properties": { + "access": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "CreatePartnerServiceAccountV1": { + "title": "CreatePartnerServiceAccountV1", + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "CreateServiceAccountV1": { + "title": "CreateServiceAccountV1", + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "redHatAccountId": { + "type": "string" + } + } + }, + "CredentialsV1": { + "title": "CredentialsV1", + "type": "object", + "properties": { + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "ExportHoldReviewV1": { + "title": "ExportHoldReviewV1", + "type": "object", + "properties": { + "lastUpdateDate": { + "type": "string", + "format": "date-time" + }, + "lastUpdatedBy": { + "type": "string" + }, + "redHatAccountId": { + "type": "string" + }, + "status": { + "type": "string" + } + } + }, + "GetAuthorizationV1": { + "title": "GetAuthorizationV1", + "type": "object", + "properties": { + "credentials": { + "$ref": "#/components/schemas/CredentialsV1" + } + } + }, + "KeyV1": { + "title": "KeyV1", + "type": "object", + "properties": { + "algorithm": { + "type": "string" + }, + "encoded": { + "type": "string" + }, + "format": { + "type": "string" + } + } + }, + "PartnerServiceAccountV1": { + "title": "PartnerServiceAccountV1", + "type": "object", + "properties": { + "created": { + "type": "string", + "format": "date-time" + }, + "createdBy": { + "type": "string" + }, + "credentials": { + "$ref": "#/components/schemas/CredentialsV1" + }, + "description": { + "type": "string" + }, + "lastUpdatedBy": { + "type": "string" + }, + "name": { + "type": "string" + }, + "partnerCode": { + "type": "string" + }, + "tokenDate": { + "type": "string", + "format": "date-time" + } + } + }, + "ResponseEntity": { + "title": "ResponseEntity", + "type": "object", + "properties": { + "body": { + "type": "object", + "properties": {} + }, + "status": { + "type": "object", + "properties": {} + } + } + }, + "Result": { + "title": "Result", + "type": "object", + "properties": { + "healthy": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "parameters": { + "type": "object", + "properties": {} + } + } + }, + "ServiceAccountV1": { + "title": "ServiceAccountV1", + "type": "object", + "properties": { + "created": { + "type": "string", + "format": "date-time" + }, + "createdBy": { + "type": "string" + }, + "credentials": { + "$ref": "#/components/schemas/CredentialsV1" + }, + "description": { + "type": "string" + }, + "lastUpdatedBy": { + "type": "string" + }, + "name": { + "type": "string" + }, + "redHatAccountId": { + "type": "string" + }, + "tokenDate": { + "type": "string", + "format": "date-time" + } + } + }, + "ServiceHealth": { + "title": "ServiceHealth", + "type": "object", + "properties": { + "parameters": { + "type": "object", + "properties": {} + }, + "results": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Result" + } + } + } + }, + "SetExportHoldV1": { + "title": "SetExportHoldV1", + "type": "object", + "properties": { + "redHatAccountId": { + "type": "string" + }, + "setTo": { + "type": "string", + "enum": [ + "on_hold", + "off_hold" + ] + } + } + }, + "Stream«ServiceAccountV1»": { + "title": "Stream«ServiceAccountV1»", + "type": "object" + }, + "SummariesV1": { + "title": "SummariesV1", + "type": "object", + "properties": { + "services": { + "$ref": "#/components/schemas/Stream«ServiceAccountV1»" + } + } + }, + "UpdateServiceAccountV1": { + "title": "UpdateServiceAccountV1", + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "regenerateToken": { + "type": "boolean" + } + } + } + } + }, + "x-original-swagger-version": "2.0" +} \ No newline at end of file diff --git a/src/rh-api/registry-authorizer.ts b/src/rh-api/registry-authorizer.ts new file mode 100644 index 0000000..74dfe83 --- /dev/null +++ b/src/rh-api/registry-authorizer.ts @@ -0,0 +1,63 @@ +/********************************************************************** + * Copyright (C) 2024-2025 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ***********************************************************************/ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ + +import createClient from 'openapi-fetch'; + +import type { paths } from './gen/registry-authorizer'; +import { ClientHolder } from './utils'; + +export const REGISTRY_REDHAT_IO1 = 'registry.redhat.io'; + +class ServiceAccountApiV1 extends ClientHolder { + serviceAccountByNameUsingGet1(name: string, rhAccountId: string) { + return this.client.GET('/v1/service-accounts/{rhAccountId}/{name}', { + params: { + path: { + name, + rhAccountId, + }, + }, + }); + } + + createServiceAccountUsingPost1(body: { name: string; description: string; redHatAccountId: string }) { + return this.client.POST('/v1/service-accounts', { + body, + }); + } + + removeServiceAccountUsingDelete1(name: string, rhAccountId: string) { + return this.client.DELETE('/v1/service-accounts/{rhAccountId}/{name}', { + params: { + path: { + name, + rhAccountId, + }, + }, + }); + } +} + +export class ContainerRegistryAuthorizerClient extends ClientHolder { + public serviceAccountsApiV1: ServiceAccountApiV1; + constructor(options: { BASE: string; TOKEN: string }) { + super(createClient({ baseUrl: options.BASE }), options.TOKEN); + this.serviceAccountsApiV1 = new ServiceAccountApiV1(this.client); + } +} diff --git a/src/rh-api/subscription-schema.json b/src/rh-api/subscription-schema.json new file mode 100644 index 0000000..6083f59 --- /dev/null +++ b/src/rh-api/subscription-schema.json @@ -0,0 +1,2154 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "RHSM-API", + "description": "API for Red Hat Subscription Management", + "contact": { + "url": "https://access.redhat.com/support/cases/" + }, + "version": "2" + }, + "servers": [ + { + "url": "https://api.access.redhat.com/management/v2" + } + ], + "paths": { + "/manifests/versions": { + "get": { + "tags": [ + "manifest" + ], + "summary": "List Satellite versions", + "description": "Returns list of Satellite version 6.0 and above", + "operationId": "listVersionsManifest", + "responses": { + "200": { + "description": "list of Satellite version", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ManifestVersion" + } + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/manifests/{uuid}": { + "get": { + "tags": [ + "manifest" + ], + "summary": "Get an Manifest by UUID", + "description": "System, RHUI, Hypervisor, SAM are unsupported manifest types", + "operationId": "showManifest", + "parameters": [ + { + "name": "uuid", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "include", + "in": "query", + "description": "Show more details about a manifest", + "schema": { + "type": "string", + "enum": [ + "entitlements" + ] + } + } + ], + "responses": { + "200": { + "description": "success response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "$ref": "#/components/schemas/ManifestDetails" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + }, + "put": { + "tags": [ + "manifest" + ], + "summary": "Update a manifest", + "description": "Allows to update simpleContentAccess for Satellite of version 6.3 and\nabove\nPossible value for simpleContentAccess are:\n\n- enabled\n- disabled", + "operationId": "updateManifest", + "parameters": [ + { + "name": "uuid", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "required": [ + "simpleContentAccess" + ], + "type": "object", + "properties": { + "simpleContentAccess": { + "type": "string" + } + } + } + } + }, + "required": false + }, + "responses": { + "204": { + "$ref": "#/components/responses/NoContent" + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + }, + "x-codegen-request-body-name": "manifest" + }, + "delete": { + "tags": [ + "manifest" + ], + "summary": "Remove manifest profile", + "description": "The default success response will be 204\n\nSystem, RHUI, Hypervisor, SAM are unsupported manifet types", + "operationId": "removeManifest", + "parameters": [ + { + "name": "uuid", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "force", + "in": "query", + "description": "Deleting a subscription manifest can have significant impacts on your hosts and activation keys.\nWe require a force parameter to make sure the delete operation is intentional.", + "required": true, + "schema": { + "type": "boolean", + "enum": [ + true + ] + } + } + ], + "responses": { + "204": { + "description": "Successfully removed", + "content": {} + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + }, + "504": { + "$ref": "#/components/responses/GatewayTimeout" + } + } + } + }, + "/manifests/{uuid}/entitlements": { + "post": { + "tags": [ + "manifest" + ], + "summary": "Attach entitlement to Manifest", + "description": "Satellite 5.6 or higher versions are only supported.", + "operationId": "attachEntitlementManifest", + "parameters": [ + { + "name": "pool", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "quantity", + "in": "query", + "description": "quantity you want to attach", + "schema": { + "type": "integer" + } + }, + { + "name": "uuid", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "$ref": "#/components/schemas/ManifestDetails" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + }, + "504": { + "$ref": "#/components/responses/GatewayTimeout" + } + } + } + }, + "/manifests/{uuid}/entitlements/{EntitlementID}": { + "put": { + "tags": [ + "manifest" + ], + "summary": "Update attached entitlement to manifest", + "description": "The default success response will be 200.\n\nSystem, RHUI, Hypervisor, SAM are unsupported manifest types", + "operationId": "updateEntitlementManifest", + "parameters": [ + { + "name": "uuid", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "EntitlementID", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "quantity", + "in": "query", + "description": "maxItem: quantity must be less than or equal to the maximum number of allowed entitlements in the entitlement pool\nminItem: 1", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Success response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "$ref": "#/components/schemas/ManifestDetails" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + }, + "delete": { + "tags": [ + "manifest" + ], + "summary": "Remove entitlement from the manifest", + "description": "The default success response will be 204.", + "operationId": "removeManifestEntitlement", + "parameters": [ + { + "name": "uuid", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "EntitlementID", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "successfully removed", + "content": {} + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/manifests": { + "get": { + "tags": [ + "manifest" + ], + "summary": "List all manifests for a user", + "description": "The default and max number of results in a response are 100.\nSatellite 6.0 or higher versions are only supported.", + "operationId": "listManifests", + "parameters": [ + { + "name": "limit", + "in": "query", + "description": "max number of results you want", + "schema": { + "type": "integer" + } + }, + { + "name": "offset", + "in": "query", + "description": "index from which you want next items", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "list of manifests", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Manifest" + } + }, + "pagination": { + "$ref": "#/components/schemas/APIPageParam" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + }, + "post": { + "tags": [ + "manifest" + ], + "summary": "Create Manifest", + "description": "Create Manifest by name and version(optional).\nCustomers can use any version listed in the `/v2/manifests/versions`\nendpoint (use attribute `value`).\nIf no version is specified, it will take the latest available version\n for Manifest.", + "operationId": "createManifest", + "parameters": [ + { + "name": "Name", + "in": "query", + "description": "must be less than 100 characters and use only numbers, letters, underscores, hyphens, and periods", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "version", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Success", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "$ref": "#/components/schemas/ManifestSummary" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/organization": { + "get": { + "tags": [ + "organization" + ], + "summary": "Get details of the user's organization", + "description": "Show Simple Content Access details of user's organization", + "operationId": "checkOrgSCACapability", + "parameters": [ + { + "name": "include", + "in": "query", + "description": "Request for system purpose attributes in response", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Organization details", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "$ref": "#/components/schemas/OrgSimpleContentAccess" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/products": { + "get": { + "tags": [ + "products" + ], + "summary": "List all the products from user's subscription", + "description": "Get list of all the products of user's subscription. The products are from subscriptions that have not expired or expired within last 30 days.\n", + "operationId": "listProducts", + "parameters": [ + { + "name": "status", + "in": "query", + "description": "Filters products based on subscription status", + "schema": { + "type": "string", + "enum": [ + "expired", + "expiringSoon", + "active", + "futureDated" + ] + } + } + ], + "responses": { + "200": { + "description": "Product list", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ProductList" + } + } + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/products/export": { + "get": { + "tags": [ + "products" + ], + "summary": "Export subscriptions", + "description": "Export a csv file of all subscriptions", + "responses": { + "200": { + "description": "Export", + "content": { + "text/csv": { + "schema": { + "type": "string", + "format": "binary" + }, + "example": "Name,SKU,Service level,Support type,Capacity name,Capacity quantity,Contract number,Quantity,Start date,End date,Status (Active, Expired, Future Dated)\nExample Name, Example SKU, Example Service level, Example Support type, Example Capacity name, Example Contract number, Example Quantity, Example Start date, Example End date, Example Status\n" + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/products/{SKU}": { + "get": { + "tags": [ + "products" + ], + "summary": "Show product", + "description": "Get a single product by SKU", + "operationId": "showProduct", + "parameters": [ + { + "name": "SKU", + "in": "path", + "description": "SKU of the product to show", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Product", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "$ref": "#/components/schemas/ProductList" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/products/status": { + "get": { + "tags": [ + "products" + ], + "summary": "Get user's subscription quantities by status", + "description": "Get counts of user's subscriptions by status such as\n- active\n- expired\n- expiring soon\n- future dated ", + "operationId": "statusCounts", + "responses": { + "200": { + "description": "Status counts", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "$ref": "#/components/schemas/StatusCount" + } + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/products/RHEL/extended-update-support-versions": { + "get": { + "tags": [ + "products" + ], + "summary": "List RHEL EUS versions", + "description": "Returns the list of currently supported RHEL versions for Extended Update Support", + "responses": { + "200": { + "description": "Extended Update Support versions", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/products/RHEL/extended-update-support-products": { + "get": { + "tags": [ + "products" + ], + "summary": "List RHEL EUS products", + "description": "Returns the list of currently supported RHEL product-repo mappings for Extended Update Support", + "responses": { + "200": { + "description": "Extended Update Support versions", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EusProductList" + } + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/manifests/{uuid}/pools": { + "get": { + "tags": [ + "manifest" + ], + "summary": "List all pools for a manifest", + "description": "Satellite 5.6 or higher versions are only supported.", + "operationId": "listManifestPools", + "parameters": [ + { + "name": "limit", + "in": "query", + "description": "max number of results you want", + "schema": { + "type": "integer" + } + }, + { + "name": "offset", + "in": "query", + "description": "index from which you want next items", + "schema": { + "type": "integer" + } + }, + { + "name": "future", + "in": "query", + "description": "include future dated pools for satellite 6.3 or higher", + "schema": { + "type": "boolean", + "enum": [ + true + ] + } + }, + { + "name": "uuid", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "list of pools available for the manifest", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/poolsListMock" + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/manifests/{uuid}/export": { + "get": { + "tags": [ + "manifest" + ], + "summary": "Trigger manifest export", + "description": "Starts job to generate export for a manifest. To check the status of the export job visit the href in the response.\n\nSatellite 6.0 or higher versions are only supported.", + "operationId": "exportManifest", + "parameters": [ + { + "name": "uuid", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "ExportManifest200 is the success response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "$ref": "#/components/schemas/exportResponse" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/manifests/{uuid}/exportJob/{ExportJobID}": { + "get": { + "tags": [ + "manifest" + ], + "summary": "Check status of manifest export", + "description": "Returns export download link in response.", + "operationId": "exportJobManifest", + "parameters": [ + { + "name": "uuid", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ExportJobID", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "ExportJobManifest200 is the success response", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "$ref": "#/components/schemas/exportJobResponse" + } + } + } + } + } + }, + "202": { + "description": "AcceptedExportJob202 is a response for accepted and in progress job", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "$ref": "#/components/schemas/ongoingExportJobResponse" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "406": { + "$ref": "#/components/responses/NotAcceptable" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/manifests/{uuid}/export/{ExportID}": { + "get": { + "tags": [ + "manifest" + ], + "summary": "Download manifest", + "description": "Success response contains a zip file. The link is one-time download and expires after one try. Trigger export job to get another download link.\n\nContent-Type: application/zip", + "operationId": "getExportManifest", + "parameters": [ + { + "name": "uuid", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "ExportID", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "GetExportManifest200 is the success response", + "content": { + "application/zip": { + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/activation_keys": { + "get": { + "tags": [ + "activationKey" + ], + "summary": "List activation keys", + "description": "Returns a list of activation keys on the account including service level, role, additionalRepositories, usage, and release version (if applicable). Additional Repositories and release version will be an empty set in case it is not set.", + "operationId": "listActivationKeys", + "responses": { + "200": { + "description": "Array of activation keys", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ActivationKeys" + } + } + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + }, + "post": { + "tags": [ + "activationKey" + ], + "summary": "Create activation key", + "description": "Creates an activation key by name, release version and system purpose attributes, that are service level, role and usage. In the request body, \"name\" should be present and unique and can only contain letters, numbers, underscores, or hyphens. The response will have name and additionalRepositories as fixed fields. AdditionalRepositories field will always be empty for a new activation key. Role, serviceLevel, usage and releaseVersion are conditional fields, will be present in response only when they have values.", + "operationId": "createActivationKeys", + "requestBody": { + "description": "Create an activation key", + "content": { + "application/json": { + "schema": { + "required": [ + "name" + ], + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Name should be present, unique and can only contain letters, numbers, underscores, or hyphens" + }, + "serviceLevel": { + "type": "string" + }, + "role": { + "type": "string" + }, + "usage": { + "type": "string" + }, + "releaseVersion": { + "type": "string" + }, + "additionalRepositories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "repositoryLabel": { + "type": "string" + } + } + } + } + } + } + } + }, + "required": false + }, + "responses": { + "200": { + "description": "Activation key", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "$ref": "#/components/schemas/ActivationKeys" + } + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + }, + "x-codegen-request-body-name": "activationKey" + } + }, + "/activation_keys/{name}": { + "get": { + "tags": [ + "activationKey" + ], + "summary": "Get activation key", + "description": "Get activation key by name", + "operationId": "showActivationKey", + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Activation key", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "$ref": "#/components/schemas/ActivationKeys" + } + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + }, + "put": { + "tags": [ + "activationKey" + ], + "summary": "Update activation key", + "description": "Updates an existing activation key with one or more fields as provided in request. It also returns additionalRepositories field which will be empty set when it is empty", + "operationId": "updateActivationKeys", + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "Update an activation key", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "serviceLevel": { + "type": "string" + }, + "role": { + "type": "string" + }, + "usage": { + "type": "string" + }, + "releaseVersion": { + "type": "string" + } + } + } + } + }, + "required": false + }, + "responses": { + "200": { + "description": "Activation key", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "$ref": "#/components/schemas/ActivationKeys" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + }, + "x-codegen-request-body-name": "activationKey" + }, + "delete": { + "tags": [ + "activationKey" + ], + "summary": "Delete activation key", + "description": "Removes the activation key from the account based on activation key name", + "operationId": "removeActivationKeys", + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "successfully removed", + "content": {} + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + }, + "/activation_keys/{name}/additional_repositories": { + "post": { + "tags": [ + "activationKey" + ], + "summary": "Add Additional Repositories", + "description": "Add additional repositories to an activation key by providing activation key name and repository labels. Customers can use any respositories listed in the `/v2/activation_keys/{name}/available_repositories` endpoint (use attribute `repositoryLabel`). Empty value is not supported and maximum length of repository label allowed is upto 255 characters.", + "operationId": "addAdditionalRepositories", + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "Add Additional repositories", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AdditionalRepositories" + } + } + } + }, + "required": false + }, + "responses": { + "200": { + "description": "list of additional repositories", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AdditionalRepositories" + } + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + }, + "x-codegen-request-body-name": "activationKey" + }, + "delete": { + "tags": [ + "activationKey" + ], + "summary": "Delete Additional Repositories", + "description": "Removes the additional repositories from an activation key by providing activation key name and repository labels", + "operationId": "removeActivationKeyAdditionalRepositories", + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AdditionalRepositories" + } + } + } + }, + "required": false + }, + "responses": { + "204": { + "$ref": "#/components/responses/NoContent" + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + }, + "x-codegen-request-body-name": "additionalRepositories" + } + }, + "/activation_keys/{name}/available_repositories": { + "get": { + "tags": [ + "activationKey" + ], + "summary": "List Available Repositories", + "description": "Returns the list of RPM repositories available to an activation key that can be added as an additional repository. Available repositories are calculated by negating the additional repositories from the set of total RPM repositories. It can be an empty set if there are no RPM repositories or all of the repositories are already added to an activation key.", + "operationId": "listAvailableRepositories", + "parameters": [ + { + "name": "name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "max number of results you want", + "schema": { + "type": "integer" + } + }, + { + "name": "offset", + "in": "query", + "description": "index from which you want next items", + "schema": { + "type": "integer" + } + }, + { + "name": "default", + "in": "query", + "description": "Filters available repos based off default status", + "schema": { + "type": "string", + "enum": [ + "Disabled" + ] + } + } + ], + "responses": { + "200": { + "description": "list of available repositories", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "body": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AvailableRepositories" + } + }, + "pagination": { + "$ref": "#/components/schemas/APIPageParam" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + } + } + } + }, + "components": { + "schemas": { + "ManifestDetails": { + "type": "object", + "properties": { + "simpleContentAccess": { + "type": "string" + }, + "createdBy": { + "type": "string" + }, + "createdDate": { + "$ref": "#/components/schemas/Date" + }, + "entitlementsAttached": { + "$ref": "#/components/schemas/EntitlementsAttached" + }, + "entitlementsAttachedQuantity": { + "type": "integer" + }, + "lastModified": { + "$ref": "#/components/schemas/Date" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "uuid": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "description": "details of a manifest" + }, + "ManifestVersion": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "description": "List of satellite version" + }, + "Manifest": { + "title": "Manifest is an entity that consumes entitlements. Also referred as a Distributor.", + "type": "object", + "properties": { + "entitlementQuantity": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "url": { + "type": "string" + }, + "uuid": { + "type": "string" + }, + "version": { + "type": "string" + }, + "simpleContentAccess": { + "type": "string" + } + } + }, + "ErrorDetails": { + "type": "object", + "properties": { + "code": { + "type": "integer" + }, + "message": { + "type": "string" + } + }, + "description": "ErrorDetails details the Error in ErrorResponse" + }, + "Date": { + "type": "string", + "description": "Date format used in API responses.", + "example": "2006-01-02T15:04:05.000Z" + }, + "EntitlementsAttached": { + "type": "object", + "properties": { + "reason": { + "type": "string" + }, + "valid": { + "type": "boolean" + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EntitlementsAttachedValue" + } + } + }, + "description": "Details of all the entitlements attached and their status." + }, + "EntitlementsAttachedValue": { + "type": "object", + "properties": { + "contractNumber": { + "type": "string" + }, + "entitlementQuantity": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "sku": { + "type": "string" + }, + "subscriptionName": { + "type": "string" + }, + "startDate": { + "$ref": "#/components/schemas/Date" + }, + "endDate": { + "$ref": "#/components/schemas/Date" + } + }, + "description": "Detail of each entitlement attached" + }, + "poolsListMock": { + "type": "object", + "properties": { + "body": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PoolDetail" + } + }, + "pagination": { + "$ref": "#/components/schemas/APIPageParam" + } + } + }, + "PoolDetail": { + "type": "object", + "properties": { + "contractNumber": { + "type": "string" + }, + "endDate": { + "$ref": "#/components/schemas/Date" + }, + "entitlementsAvailable": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "serviceLevel": { + "type": "string" + }, + "sku": { + "type": "string" + }, + "startDate": { + "$ref": "#/components/schemas/Date" + }, + "subscriptionName": { + "type": "string" + }, + "subscriptionNumber": { + "type": "string" + } + }, + "description": "PoolDetail is an entry in the system/allocation pools listing" + }, + "APIPageParam": { + "type": "object", + "properties": { + "count": { + "type": "integer" + }, + "limit": { + "type": "integer" + }, + "offset": { + "type": "integer" + } + }, + "description": "APIPageParam details the pagination parameters in APIResponse" + }, + "ManifestSummary": { + "type": "object", + "properties": { + "contentAccessMode": { + "type": "string" + }, + "createdBy": { + "type": "string" + }, + "createdDate": { + "$ref": "#/components/schemas/Date" + }, + "entitlementsAttachedQuantity": { + "type": "integer" + }, + "lastModified": { + "$ref": "#/components/schemas/Date" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "uuid": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "description": "details of a manifest" + }, + "OrgSimpleContentAccess": { + "title": "Organization Simple Content Access details.", + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "simpleContentAccessCapable": { + "type": "boolean" + }, + "simpleContentAccess": { + "type": "string" + }, + "systemPurposeAttributes": { + "$ref": "#/components/schemas/SystemPurposeAttributes" + } + } + }, + "SystemPurposeAttributes": { + "type": "object", + "properties": { + "roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "usage": { + "type": "array", + "items": { + "type": "string" + } + }, + "serviceLevel": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "description": "System purpose settings available to an organization" + }, + "exportResponse": { + "type": "object", + "properties": { + "exportJobID": { + "type": "string" + }, + "href": { + "type": "string" + } + } + }, + "exportJobResponse": { + "type": "object", + "properties": { + "exportID": { + "type": "string" + }, + "href": { + "type": "string" + } + } + }, + "ongoingExportJobResponse": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + }, + "ActivationKeys": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "serviceLevel": { + "type": "string" + }, + "role": { + "type": "string" + }, + "usage": { + "type": "string" + }, + "additionalRepositories": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AdditionalRepositories" + } + }, + "releaseVersion": { + "type": "string" + } + } + }, + "ProductList": { + "title": "List of products from subscriptions", + "type": "object", + "properties": { + "sku": { + "type": "string" + }, + "name": { + "type": "boolean" + }, + "productLine": { + "type": "string" + }, + "quantity": { + "type": "integer" + }, + "serviceType": { + "type": "string" + }, + "serviceLevel": { + "type": "string" + }, + "capacity": { + "$ref": "#/components/schemas/Capacity" + } + } + }, + "EusProductList": { + "title": "List of RHEL EUS product-repo mappings", + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "engID": { + "type": "integer" + }, + "configurations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "version": { + "type": "string" + }, + "repositories": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + }, + "Capacity": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "quantity": { + "type": "string" + } + } + }, + "AdditionalRepositories": { + "type": "object", + "properties": { + "repositoryName": { + "type": "string" + }, + "repositoryLabel": { + "type": "string" + } + } + }, + "AvailableRepositories": { + "type": "object", + "properties": { + "repositoryLabel": { + "type": "string" + }, + "repositoryName": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "default": { + "type": "string" + }, + "engineeringProduct": { + "type": "string" + } + } + }, + "StatusCount": { + "title": "Status counts of user's subscriptions", + "type": "object", + "properties": { + "active": { + "type": "integer" + }, + "expired": { + "type": "integer" + }, + "expiringSoon": { + "type": "integer" + }, + "futureDated": { + "type": "integer" + } + } + } + }, + "responses": { + "BadRequest": { + "description": "BadRequest error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "$ref": "#/components/schemas/ErrorDetails" + } + } + } + } + } + }, + "Forbidden": { + "description": "Forbidden error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "$ref": "#/components/schemas/ErrorDetails" + } + } + } + } + } + }, + "GatewayTimeout": { + "description": "GatewayTimeout error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "$ref": "#/components/schemas/ErrorDetails" + } + } + } + } + } + }, + "InternalServerError": { + "description": "InternalServerError error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "$ref": "#/components/schemas/ErrorDetails" + } + } + } + } + } + }, + "NotFound": { + "description": "NotFound error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "$ref": "#/components/schemas/ErrorDetails" + } + } + } + } + } + }, + "Unauthorized": { + "description": "Unauthorized error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "$ref": "#/components/schemas/ErrorDetails" + } + } + } + } + } + }, + "NoContent": { + "description": "No Content", + "content": {} + }, + "NotAcceptable": { + "description": "NotAcceptable error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "$ref": "#/components/schemas/ErrorDetails" + } + } + } + } + } + } + } + }, + "x-original-swagger-version": "2.0" +} \ No newline at end of file diff --git a/src/subscription.ts b/src/rh-api/subscription.ts similarity index 59% rename from src/subscription.ts rename to src/rh-api/subscription.ts index a22f3be..97f5b90 100644 --- a/src/subscription.ts +++ b/src/rh-api/subscription.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2024 Red Hat, Inc. + * Copyright (C) 2024-2025 Red Hat, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,27 +15,18 @@ * * SPDX-License-Identifier: Apache-2.0 ***********************************************************************/ +/* eslint-disable @typescript-eslint/explicit-function-return-type */ import { accessSync, constants, readFileSync } from 'node:fs'; import { homedir } from 'node:os'; import path from 'node:path'; -import * as extensionApi from '@podman-desktop/api'; +import createClient from 'openapi-fetch'; -export const REGISTRY_REDHAT_IO = 'registry.redhat.io'; +import type { paths } from './gen/subscription'; +import { ClientHolder } from './utils'; -export async function signIntoRedHatDeveloperAccount( - createIfNone = true, -): Promise { - return extensionApi.authentication.getSession( - 'redhat.authentication-provider', - [ - 'api.iam.registry_service_accounts', //scope that gives access to hydra service accounts API - 'api.console', - ], // scope that gives access to console.redhat.com APIs - { createIfNone }, - ); -} +export const REGISTRY_REDHAT_IO = 'registry.redhat.io'; // TODO: add listRegistries to registry API to allow search by // registry URL @@ -59,3 +50,35 @@ export function isRedHatRegistryConfigured(): boolean { } return configured; } + +export class ActivationKey extends ClientHolder { + async createActivationKeys(body: { name: string; role: string; usage: string; serviceLevel: string }) { + return this.client.POST('/activation_keys', { body }); + } + showActivationKey(name: string) { + return this.client.GET('/activation_keys/{name}', { + params: { + path: { + name, + }, + }, + }); + } +} + +export class Organization extends ClientHolder { + async checkOrgScaCapability() { + const response = await this.client.GET('/organization'); + return response.data; + } +} + +export class SubscriptionManagerClient extends ClientHolder { + activationKey: ActivationKey; + organization: Organization; + constructor(options: { BASE: string; TOKEN: string }) { + super(createClient({ baseUrl: options.BASE }), options.TOKEN); + this.activationKey = new ActivationKey(this.client); + this.organization = new Organization(this.client); + } +} diff --git a/src/rh-api/utils.ts b/src/rh-api/utils.ts new file mode 100644 index 0000000..885c44f --- /dev/null +++ b/src/rh-api/utils.ts @@ -0,0 +1,34 @@ +/********************************************************************** + * Copyright (C) 2025 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ***********************************************************************/ + +import type { Client } from 'openapi-fetch'; + +export class ClientHolder { + protected client: Client; + constructor(client: Client, token?: string) { + this.client = client; + if (token) { + this.client.use({ + onRequest({ request }) { + request.headers.set('Authorization', `Bearer ${token}`); + return request; + }, + }); + } + } +} diff --git a/src/util.ts b/src/util.ts index cf86eb5..01d0f74 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2024 Red Hat, Inc. + * Copyright (C) 2024-2025 Red Hat, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,9 @@ import { platform } from 'node:os'; +import type { AuthenticationSession } from '@podman-desktop/api'; +import { authentication } from '@podman-desktop/api'; + const windows = platform() === 'win32'; export function isWindows(): boolean { return windows; @@ -30,3 +33,14 @@ const linux = platform() === 'linux'; export function isLinux(): boolean { return linux; } + +export async function signIntoRedHatDeveloperAccount(createIfNone = true): Promise { + return authentication.getSession( + 'redhat.authentication-provider', + [ + 'api.iam.registry_service_accounts', //scope that gives access to hydra service accounts API + 'api.console', + ], // scope that gives access to console.redhat.com APIs + { createIfNone }, + ); +}