From 757e61489a84b7b489b30bb7575213134a328335 Mon Sep 17 00:00:00 2001 From: SirBerg Date: Wed, 18 Jun 2025 21:32:23 +0200 Subject: [PATCH 1/2] Initialize Iglu Controller OpenAPI Spec --- .../Controller/Builder/builder-creation.mdx | 16 + docs/Components/Controller/intro.md | 1 + docusaurus.config.ts | 9 + static/api/controller.yml | 459 ++++++++++++++++++ ...-controller_scheduler_builder_relation.png | Bin 0 -> 36008 bytes 5 files changed, 485 insertions(+) create mode 100644 docs/Components/Controller/Builder/builder-creation.mdx create mode 100644 docs/Components/Controller/intro.md create mode 100644 static/api/controller.yml create mode 100644 static/img/docs/Controller/Builder/iglu-controller_scheduler_builder_relation.png diff --git a/docs/Components/Controller/Builder/builder-creation.mdx b/docs/Components/Controller/Builder/builder-creation.mdx new file mode 100644 index 00000000..0d5c76d4 --- /dev/null +++ b/docs/Components/Controller/Builder/builder-creation.mdx @@ -0,0 +1,16 @@ +--- +id: builder-controller-relation +title: "Builder Controller Relation" +description: "This is how the Iglu Controller communicates with Builders." +--- + +## How are builders started? +Builders (or rather the containers) are not started directly by the Iglu Controller, but rather a Scheduler Server. This Scheduler server runs in the background and starts the containers when a new build is requested / according to a cron schedule. +The Scheduler Server is automatically setup when you spin up the Iglu Controller, so you don't have to worry about it. +The Files for this Scheduler are located unter `lib/scheduler` in the Iglu Controller repository. +## How does the Iglu Controller communicate with Builders / The Scheduler? +All of these compontens communicate via this schema: +![Iglu Controller Scheduler Communication](/img/docs/Controller/Builder/iglu-controller_scheduler_builder_relation.png) +## How can I add a new Builder? +Well first you can create one via the Iglu Controller UI in the "Builders" section. +You can also create a new Builder via the Rest API of the Iglu Controller. This API is documented here: [Iglu Controller API](/docs/API/Iglu%20Controller/create-a-new-builder) \ No newline at end of file diff --git a/docs/Components/Controller/intro.md b/docs/Components/Controller/intro.md new file mode 100644 index 00000000..0e8521fa --- /dev/null +++ b/docs/Components/Controller/intro.md @@ -0,0 +1 @@ +TBA \ No newline at end of file diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 4928264f..01f73d8d 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -86,6 +86,15 @@ const config: Config = { }, hideSendButton: true, } satisfies OpenApiPlugin.Options, + controller: { + specPath: "static/api/controller.yml", + outputDir: "docs/API/Iglu Controller", + sidebarOptions: { + groupPathsBy: "tag", + categoryLinkSource: "tag", + }, + hideSendButton: true, + } satisfies OpenApiPlugin.Options, } }, ] diff --git a/static/api/controller.yml b/static/api/controller.yml new file mode 100644 index 00000000..dca2585d --- /dev/null +++ b/static/api/controller.yml @@ -0,0 +1,459 @@ +openapi: 3.0.4 +info: + title: Iglu Controller API + description: |- + This is the documentation of the Iglu Controller API. The Controller is part of the [Iglu Project](https://github.com/iglu-sh). + version: 0.0.1 +externalDocs: + description: Read more on the official Iglu Docs + url: https://docs.iglu.sh/ +servers: + - url: https://example.com/api/v1 +paths: + /user: + get: + summary: returns user information for an API Token + description: |- + Get user information about a given API Token + security: + - api_key: [] + responses: + '200': + description: "Returned if a user was found" + content: + "application/json": + schema: + $ref: '#/components/schemas/userData' + '401': + description: 'A 401 Header is returned if the Auth was incorrect, not provided or the bearer token was corrupted' + content: + "application/json": + schema: + type: object + properties: + error: + type: string + '500': + description: "A 500 Error is returned when the Server encounters any issue." + content: + "application/json": + schema: + type: object + properties: + error: + type: string + /builder: + get: + summary: Get Info about all Builders for a Cache + description: |- + Returns all Builders for a given CacheID + parameters: + - name: cacheID + in: query + required: true + description: 'The Cache ID that you want to query.' + schema: + type: integer + format: int64 + responses: + '200': + description: 'A 200 Is returned if the Auth was correct and a builder with the given ID was found' + content: + "application/json": + schema: + type: array + items: + $ref: '#/components/schemas/dbBuilder' + '400': + description: 'A 400 Error is returned if the given cacheID is invalid or not found' + content: + "application/json": + schema: + type: object + properties: + error: + type: string + '403': + description: 'A 403 Error is returned if the request was not properly authenticated' + content: + "application/json": + schema: + type: object + properties: + error: + type: string + '500': + description: 'A 500 Error is returned in case the Server encounters a generic Error in the fetching of the builders' + content: + "application/json": + schema: + type: object + properties: + error: + type: string + post: + summary: 'Create a new Builder' + description: |- + Create a new Builder using the REST API. + parameters: + - name: cacheID + in: query + required: true + description: 'The Cache ID that you want to create the builder in.' + schema: + type: integer + format: int64 + requestBody: + description: Create a new Builder + content: + application/json: + schema: + $ref: '#/components/schemas/builderCreationRequest' + responses: + '200': + description: 'Returned if the request was successfull' + content: + application/json: + schema: + $ref: '#/components/schemas/builderCreationRequest' + '401': + description: 'Returned if the request was invalid, i.e no body or the cacheID is invalid or not found' + content: + application/json: + schema: + $ref: '#/components/schemas/error' + '403': + description: 'Returned if the request was made aunauthenticated' + content: + application/json: + schema: + $ref: '#/components/schemas/error' + '400': + description: 'Returned if the request body was malformed or is deemed invalid according to the schema' + content: + application/json: + schema: + $ref: '#/components/schemas/error' + '500': + description: 'Returned if the Server encounters any errors during the creation process' + content: + application/json: + schema: + $ref: '#/components/schemas/error' + + + + + +security: + - api_key: [] + +components: + securitySchemes: + api_key: + type: http + scheme: bearer + bearerFormat: string + description: 'An API Key in the format bearer ' + schemas: + error: + type: object + properties: + error: + type: string + + hash: + type: object + properties: + id: + type: number + path: + type: string + cache: + type: number + updatedat: + type: string + cderiver: + type: string + cfilehash: + type: string + cfilesize: + type: string + creferences: + type: string + csig: + type: string + cstorehash: + type: string + cstoresuffix: + type: string + parts: + type: string + compression: + type: string + + cache: + type: object + properties: + id: + type: number + githubusername: + type: string + ispublic: + type: boolean + name: + type: string + permission: + type: string + preferredcompressionmethod: + type: string + uri: + type: string + priority: + type: number + problems: + type: array + items: + type: object + properties: + heading: + type: string + description: + type: string + + builder: + type: object + properties: + id: + type: number + name: + type: string + description: + type: string + enabled: + type: boolean + trigger: + type: string + cron: + type: string + webhookurl: + type: string + required: ['id', 'name', 'description', 'enabled', 'trigger', 'webhookurl'] + git: + type: object + properties: + repository: + type: string + branch: + type: string + gitusername: + type: string + gitkey: + type: string + requiresauth: + type: boolean + noclone: + type: boolean + + buildoptions: + type: object + properties: + cores: + type: number + maxjobs: + type: number + keep_going: + type: boolean + extraargs: + type: string + substituters: + type: array + items: + $ref : '#/components/schemas/substituter' + parallelbuilds: + type: boolean + description: 'Defines wether or not to start new builds while an old build is already running' + command: + type: string + + cachix: + type: object + properties: + push: + type: boolean + target: + type: string + apikey: + $ref : '#/components/schemas/apikey' + signingkey: + $ref: "#/components/schemas/signingkey" + builder_id: + type: string + buildoutputdir: + type: string + id: + type: number + + builderRun: + type: object + properties: + log: + type: string + + builderDatabase: + type: + object + properties: + builder: + $ref: '#/components/schemas/builder' + git: + $ref: '#/components/schemas/git' + buildoptions: + $ref: '#/components/schemas/buildoptions' + cachix: + $ref: '#/components/schemas/cachix' + cache: + $ref: '#/components/schemas/cache' + dbBuilder: + type: + object + properties: + builder: + $ref: '#/components/schemas/builder' + git: + $ref: '#/components/schemas/git' + buildoptions: + $ref: '#/components/schemas/buildoptions' + cachix: + $ref: '#/components/schemas/cachix' + cache: + $ref: '#/components/schemas/cache' + lastrun: + $ref: '#/components/schemas/builderRun' + + signingkey: + type: object + properties: + id: + type: number + privateKey: + type: string + publicKey: + type: string + + apikey: + type: object + properties: + key: + type: number + id: + type: number + + substituter: + type: object + properties: + url: + type: string + signingKeys: + type: array + items: + type: string + + userData: + type: object + properties: + caches: + type: array + items: + $ref: '#/components/schemas/cache' + newestCashedHashes: + type: array + items: + $ref: '#/components/schemas/hash' + builderCreationRequest: + type: object + required: + - name + - description + - git + - build + - cachix + properties: + name: + type: string + description: + type: string + git: + type: object + required: + - noClone + - url + - branch + - requiresAuth + - username + - token + properties: + noClone: + type: boolean + url: + type: string + branch: + type: string + requiresAuth: + type: boolean + username: + type: string + token: + type: string + build: + type: object + required: + - command + - buildTrigger + - outputDir + - allowUnfree + - parallelBuilds + - sandboxed + - maxJobs + - cores + - substituters + properties: + command: + type: string + buildTrigger: + type: string + enum: [manual, webhook, cron] + cron: + type: string + description: Required if buildTrigger is "cron" + outputDir: + type: string + allowUnfree: + type: boolean + parallelBuilds: + type: boolean + sandboxed: + type: boolean + maxJobs: + type: integer + cores: + type: integer + substituters: + type: array + items: + $ref: '#/components/schemas/substituter' + cachix: + type: object + required: + - mode + - push + properties: + mode: + type: string + enum: [manual, auto] + cachixPublicSigningKey: + type: string + cachixSigningKey: + type: string + push: + type: boolean \ No newline at end of file diff --git a/static/img/docs/Controller/Builder/iglu-controller_scheduler_builder_relation.png b/static/img/docs/Controller/Builder/iglu-controller_scheduler_builder_relation.png new file mode 100644 index 0000000000000000000000000000000000000000..3f2506f3ef60a43ce1a354a8dd09cb7b773f6e0d GIT binary patch literal 36008 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 Date: Wed, 18 Jun 2025 21:32:51 +0200 Subject: [PATCH 2/2] Initialize Iglu Controller OpenAPI Spec --- .../create-a-new-builder.api.mdx | 72 +++++++++++++++++++ ...nfo-about-all-builders-for-a-cache.api.mdx | 72 +++++++++++++++++++ .../iglu-controller-api.info.mdx | 35 +++++++++ ...-user-information-for-an-api-token.api.mdx | 64 +++++++++++++++++ docs/API/Iglu Controller/sidebar.ts | 24 +++++++ 5 files changed, 267 insertions(+) create mode 100644 docs/API/Iglu Controller/create-a-new-builder.api.mdx create mode 100644 docs/API/Iglu Controller/get-info-about-all-builders-for-a-cache.api.mdx create mode 100644 docs/API/Iglu Controller/iglu-controller-api.info.mdx create mode 100644 docs/API/Iglu Controller/returns-user-information-for-an-api-token.api.mdx create mode 100644 docs/API/Iglu Controller/sidebar.ts diff --git a/docs/API/Iglu Controller/create-a-new-builder.api.mdx b/docs/API/Iglu Controller/create-a-new-builder.api.mdx new file mode 100644 index 00000000..13d2bb30 --- /dev/null +++ b/docs/API/Iglu Controller/create-a-new-builder.api.mdx @@ -0,0 +1,72 @@ +--- +id: create-a-new-builder +title: "Create a new Builder" +description: "Create a new Builder using the REST API." +sidebar_label: "Create a new Builder" +hide_title: true +hide_table_of_contents: true +api: eJztWEtvGzcQ/ivEnhJAluQ27cEoCjh2Crg91LCVk2IU3N2RljGX3PBhWxD03ztD7lNax3Z6cA/2wdCSw+E3w5lvhtwmOdjMiMoJrZKT5MwAd8A4U3DPPnohczDMW6HWzBXArj5dL9jp5cU0mSQVN7wEB8YmJ8ttovADFWQ8K+DiHOcF6fvmwWzww8A3LwzkyYkzHiZ7uy5Q9RktZBfnuA93bKM9u+fKMadZFjHR/mmNSChCYHFFyZOTbeI2FW0ulIM1GJxaaVNyF4d+/ZDsdjcRA1j3UecbWvO04agn06hSOZLnVSVFxkl+9tXSou0hAp1+hcwNDF5G1wxtniRrQWLBINoHrRcPCaKsjK7AOAGW1EavtuqtM3gUyW7PgSPzpP4pWPpMakXIvJGExXCVFZ2QPfWOPr0FU5vg9C2oEZS1pm7DVGsJXBESUj6GsN5ubGoAYFxpg2lseUR5OLPbNQ5/wjOZLkuu8uZ8FkasY1hp7yrvzgX95lLq+89qZQDqbJASZAgdS8GJClL9AKSl5A9/6tSGeEKzaNan1gnnQ/oc+LPZf9RtfUQHApMElC/JBlTgOR3rPaSF1re0ucFgudnVP0bWDlPiqvYIEyvW35UJy74EHV8SQtQ5ZQxv302jR7nnuVGZzpmj041/D5lg17h8dGpwCp0EN4YTaQkHpR2LleFpPRbgVqwV/vwLNs9R3g9SxCTDWIePJnYtTzwRv6XOQ0x6WxwGV5h8TuBw73QMl7DppU+R/65bo0ZtjqJPCAVcIwc5sL2m+sDLGI9XkbxrITzRSisbDfppPj/k8ytw3qgYvFQ5avLHomKZ9VkG1q68lG8U/0bxbxT/RvFvFP9/o/gPL2H1FHv6QO0ll9T6o4QOQZwD0IdQd1yKnPEMQyUPtxkdFNTs/h+qwNDzYIweS5Ke1VGkMfL4ZaWrNmTCxBSY0tFwNJXk6qsXmd3YizNKO7bSPlDdaxn588uMLHmONzGvMDoLhEsw4fXg//KcQLwGc4e0CSpDVxPXMK42LKjBIPSmuUBndawzhEQ9yCtZRYQKrtBIJUmlbdDGqRAns7S9+9pgU7zdBwJMCucqezKbwQMvKwlTLGIzXonZ3XFCF2wLGVrqNmEFjv9zS+ywvOnPXZM5EXEr0WIm/c29PhAEcBOgxB9/NJf6R6rZqaK3CYachAkQ3B2fAVhczn7baG+OQuvwe3AM+fiqexX4FM3qmrLHNmqH6xasbY7i40Z0VivUdEHdyLD5qRe17U4nV3c5+63BoH/o7TNoGzqSj61AJ9cr5t3goIZHRPtVO4726nQcaCvzvC3E8/2620ZQu9+gci6bcQyVQQWMhaxnyiNlqtN7WJ26uViUCDUdvlArHWKvzo6LtfTsDJPRaLTaUCgdHPyiIHK1IbZynfkSEzfms448MKJkysLzVjeG69G1rlmyDGsujaa0vnnX5BiGVuHTkGICBY5s8Z7evCgjI5b5dD49DrUWExg91AvbRx6z9i4ULfG85NWvzlQHD25WSS76/X+kkGVT16kvKYhccGi7TbmFz0budjQcnwUpLHJheSopmlZc2v2XwT7Id02z+p794HvhKPbAQL1nSyycnqQCo91xIwheYDG0BjjZRbjjsrOI7mhBmru1Bzy+mzQrTvHqWbnvyt70yPny7+sFpXb9Zlnng+H3xCL4H3FiQgdvBU4NY9tEcrX2fE2yUSf9/Qvfnpfu +sidebar_class_name: "post api-method" +info_path: docs/API/Iglu Controller/iglu-controller-api +custom_edit_url: null +hide_send_button: true +--- + +import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; +import ParamsDetails from "@theme/ParamsDetails"; +import RequestSchema from "@theme/RequestSchema"; +import StatusCodes from "@theme/StatusCodes"; +import OperationTabs from "@theme/OperationTabs"; +import TabItem from "@theme/TabItem"; +import Heading from "@theme/Heading"; + + + + + + + + + + +Create a new Builder using the REST API. + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/API/Iglu Controller/get-info-about-all-builders-for-a-cache.api.mdx b/docs/API/Iglu Controller/get-info-about-all-builders-for-a-cache.api.mdx new file mode 100644 index 00000000..ecdaf05c --- /dev/null +++ b/docs/API/Iglu Controller/get-info-about-all-builders-for-a-cache.api.mdx @@ -0,0 +1,72 @@ +--- +id: get-info-about-all-builders-for-a-cache +title: "Get Info about all Builders for a Cache" +description: "Returns all Builders for a given CacheID" +sidebar_label: "Get Info about all Builders for a Cache" +hide_title: true +hide_table_of_contents: true +api: eJy9V1Fv2zgM/iuCnzaga7rbdg/F4YBu3Q3BXoZu9xQUhWwztlpZ8igpbRDkvx8p24mTytdeD9hTU4siP1LkR3KTleAKVK1X1mTn2RX4gMYJqbX4GJQuAZ1YWhRSVGoFRnySRQ3zy+wkayXKBjwJZOeLTWboH1JQ7M4V6/sZANf0D8LPoBDK7NxjgJMjqz9q6BSL+aXwtfRibYO4l8YLb0XUcUpKHEk0MjvfZH7dsjFlPFSAdEQQG+m7T7+/z7bba7bpWmscOL7x29kZ/zm0eyHos5g7gdFtKIVakn0QF8HXZN+JwiJC4YU0JYVA5F1IxL2icxbsgkKoWXhpgykJTGEJl/FsT7atVoVke7Nbx0Y3j92QiJKDpDw0bvTd5rdkm0ONtgX0qnOlB/G0oCpHMiY0OV3anvQvtTtwHpWp+OAgOIlzMDLXMFaaW6tBGj4kqao6QLW/WOCExnvIa2vvAurE8XacNgv2psd+iHSPaw/iQDOlgldeR7x96Eh1pfzTEURorVPeUg6n4OcoTVEnj0h9cICTsabzO0hr7Z12kpIwHWtjC20NpA63e2fZQwbJPtsYq2ckFyU8uGTaNPLh1ubpszuA9qay7EASMDx4lBIrl3TYhdwR6NBxyUvLIp1EpF1Vhn5+hfVzlO+SbxTIEb4YYGY+rUHHyLqEx8f8dglLZcCJeyDOQEF0amykNuclemHgvmMWkqiVBmIbYXXZfROK2RhBlmuBwZihpGzTECmly+Yg3Yen50vEserh6VC2wU1kHuGtwCfjLFt1mNETyg+F9jmUZKuRM73+/Ys+y9oEB7aoVtLD14kSbENOtJ0+HSfGHshQaIA3KvUqQx0G3wZfqjRPPhWC/v36l4QXe0/MUIf8X/lJuS4GEwQ0dY1sN8q5qQ7SIiyBOmpJ6Uu/oyDNELVNhyygmlCjLCqfziOKAHWD5n8wSU3Fdkhlz+2R2+3xcwFf0pIEgnnasrYpq8cVDXgVDqm+zD8Ona2D8D497tBn8RmRCEg9Hnq6WaYf4FhAmZXUqhz46qXjzYSvwDgmYhg9eJf24N20B9w5wfk4jDHizqBeC26lBJmhwq9z4UP6ET6kH4FD7yD68R1wRX0CTEEh567I4zcYQFUMN00UXIInRjCVsF0A+vRwv8hFngr66s24LXBr5Jklmw2DFpF19KXbEWKLzmrvW3c+m8GDbFoNp8QFMyL32eptxmO7gyJ0xb1g6Oom8vzienz2ndF3AHcSO4isf9gWYs2AxAil+/HXsCr0rhw36wsjLr7NBZH/Lsrxhuiuiz9oN8E33t6B+TMWoTJLG833xTivdBCfKPxoaUpA1vbIyI+a68tF9aUtQkNPFR9oeMmEklMR96T9N7rf8vzQX1nEO9/Q8kNevxrC3JF9jLIigTeufs3LFD9Kh+Xs9Oz0bWRO6zwNFexLv819AS/m5J6QOXWu1FYY17Zj9zb77PsvG2X/fp6mxVmrpTJdD4hjXZdYi90ET8lQE1z+tNnkVDh/o95u+XO3cnLylMr1C8tSane8dY5BvrrqF43X4pm7aBJrzMPRCkz0GVgq5vVKomI4MZdPYpPhdWnRT0TZRVFA60e3HpUta9nV25fPPyj7/gFhUnLy +sidebar_class_name: "get api-method" +info_path: docs/API/Iglu Controller/iglu-controller-api +custom_edit_url: null +hide_send_button: true +--- + +import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; +import ParamsDetails from "@theme/ParamsDetails"; +import RequestSchema from "@theme/RequestSchema"; +import StatusCodes from "@theme/StatusCodes"; +import OperationTabs from "@theme/OperationTabs"; +import TabItem from "@theme/TabItem"; +import Heading from "@theme/Heading"; + + + + + + + + + + +Returns all Builders for a given CacheID + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/API/Iglu Controller/iglu-controller-api.info.mdx b/docs/API/Iglu Controller/iglu-controller-api.info.mdx new file mode 100644 index 00000000..7eb55e0a --- /dev/null +++ b/docs/API/Iglu Controller/iglu-controller-api.info.mdx @@ -0,0 +1,35 @@ +--- +id: iglu-controller-api +title: "Iglu Controller API" +description: "This is the documentation of the Iglu Controller API. The Controller is part of the [Iglu Project](https://github.com/iglu-sh)." +sidebar_label: Introduction +sidebar_position: 0 +hide_title: true +custom_edit_url: null +--- + +import ApiLogo from "@theme/ApiLogo"; +import Heading from "@theme/Heading"; +import SchemaTabs from "@theme/SchemaTabs"; +import TabItem from "@theme/TabItem"; +import Export from "@theme/ApiExplorer/Export"; + + + + + + + + + +This is the documentation of the Iglu Controller API. The Controller is part of the [Iglu Project](https://github.com/iglu-sh). + + + \ No newline at end of file diff --git a/docs/API/Iglu Controller/returns-user-information-for-an-api-token.api.mdx b/docs/API/Iglu Controller/returns-user-information-for-an-api-token.api.mdx new file mode 100644 index 00000000..49cab2c2 --- /dev/null +++ b/docs/API/Iglu Controller/returns-user-information-for-an-api-token.api.mdx @@ -0,0 +1,64 @@ +--- +id: returns-user-information-for-an-api-token +title: "returns user information for an API Token" +description: "Get user information about a given API Token" +sidebar_label: "returns user information for an API Token" +hide_title: true +hide_table_of_contents: true +api: eJy9Vk1PGzEQ/SuWT60UklC1F1RViigF1Atq6Qmhyrs7yRp27a09DqQR/70z4wQSsmmFhIoCbOz5eJ73PLNLXUEsg+3QeqeP9CmgShGCsm7qQ2t4WZnCJ1RGzewcnJpcnKtLfwtOD3SEMgWLC310tdSmsz9vgZ+vH64HOkDsvIsQ9dFSvxuP+d92sm+AKTiolJ1SdEl7Z6Ka+uQqCl56h+CQ/UzXNbYUNKObyM5LHcsaWsNPuOiAwvniBkokxy74DgLanLo0ZBg37EwIZkFmFqGN//a31YaNS20BQT8M9MxinQoG7UwLGyYRg3UzNrGxSwXh3tgsvG/AON7d60a5Wxujzcfc3Q4whRCgKn1Lz2LYAta+6jUnfvaEsT5T13M4qkDRbFfnhVWrwVScqS/1lgp29vlnoNFiw6vCnuYVB3cQ8djEGqoz/vv6nHYG617EGUWfS+oqg0C//X4VBLo0oX9zahuo6ST7d6P93a+RUkQArtyqwsZ+tP21LyP68Jessh3TdGrv+2VjAu5J+STHPlafKJXkWyTzLfps0OjM/fvx4W6zmChaVmckK+5OUYWN5oE1qEnCWtqHdaWn61HiQDmPioif24rsfBC7AkygCMgdTOzZOnXE4eu1HLqevo/zlbY/9DXDiaJldcKeW8e7qwknA/8OgZSkiHPqjwghKuMWZBoTDP8TdMK+7jR6BuIsN0aPmEGZB4wxyjhIoWGyEbt4NBrBvWm7BoakkhENitH8UPOQWA+Q7wwvI3gcI48YOAYHFxtuokIhreSHLzKonrAOnlc2z6yvQNXKpcyjbS2FjwufwoEI4pMIlWefpF/J83zWJHVM9Q2+aciBou0kuayJNPpw+MqXqSUu8vT0WZ89QYbqkjY21sif79fa5Up8LoJnpq7frEuZJ49U0pLBQazfsgC48BnLeDgeHspl9RFbI/znaaOzrOLujKcn0tPWcH/Wph8F9tKXhBWLCPc46hpjXR5LDQfN+rmSDqBJDzUh5u/LZWEi/AjNwwMv/0oQ5MWCjmmCNQXzQq8ZA5kz3F9JcCIaPSlL6Fiac9MkGQ3PbwPr7lHGpyeXZGvSVuN/JjCJvh40brERm2CKhRyVoA5WIERMlIiuzB8neUBo +sidebar_class_name: "get api-method" +info_path: docs/API/Iglu Controller/iglu-controller-api +custom_edit_url: null +hide_send_button: true +--- + +import MethodEndpoint from "@theme/ApiExplorer/MethodEndpoint"; +import ParamsDetails from "@theme/ParamsDetails"; +import RequestSchema from "@theme/RequestSchema"; +import StatusCodes from "@theme/StatusCodes"; +import OperationTabs from "@theme/OperationTabs"; +import TabItem from "@theme/TabItem"; +import Heading from "@theme/Heading"; + + + + + + + + + + +Get user information about a given API Token + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/API/Iglu Controller/sidebar.ts b/docs/API/Iglu Controller/sidebar.ts new file mode 100644 index 00000000..cf9b3a21 --- /dev/null +++ b/docs/API/Iglu Controller/sidebar.ts @@ -0,0 +1,24 @@ +import type { SidebarsConfig } from "@docusaurus/plugin-content-docs"; + +const sidebar: SidebarsConfig = { + apisidebar: [ + { + type: "doc", + id: "API/Iglu Controller/iglu-controller-api", + }, + { + type: "category", + label: "UNTAGGED", + items: [ + { + type: "doc", + id: "API/Iglu Controller/build", + label: "This route returns user information based on the provided token in the Auhtorization header", + className: "api-method get", + }, + ], + }, + ], +}; + +export default sidebar.apisidebar;