diff --git a/packages/kubekit-prepare/gen-config/sa.yaml b/packages/kubekit-prepare/gen-config/sa.yaml index 6dd854a5..22b35cf8 100644 --- a/packages/kubekit-prepare/gen-config/sa.yaml +++ b/packages/kubekit-prepare/gen-config/sa.yaml @@ -17,7 +17,7 @@ rules: - serviceaccounts verbs: - get - # for aggregate target service account rules + # for aggregate target subject rules - apiGroups: - rbac.authorization.k8s.io resources: diff --git a/packages/kubekit-prepare/package.json b/packages/kubekit-prepare/package.json index 6fc1a5b0..3027a886 100644 --- a/packages/kubekit-prepare/package.json +++ b/packages/kubekit-prepare/package.json @@ -1,6 +1,6 @@ { "name": "@kubekit/prepare", - "version": "0.0.9", + "version": "0.0.10", "main": "lib/index.js", "types": "lib/index.d.ts", "author": "kahirokunn", @@ -15,8 +15,8 @@ "homepage": "https://github.com/appthrust/kubekit-ts", "bin": "lib/bin/cli.js", "scripts": { - "build": "tsc", - "prepare": "tsc && chmod +x ./lib/bin/cli.js", + "build": "rm -rf lib && tsc", + "prepare": "rm -rf lib && tsc && chmod +x ./lib/bin/cli.js", "gen-openapi": "kubectl apply -f gen-config/sa.yaml && yarn build; chmod +x lib/bin/cli.js; yarn cli ./gen-config/openapi.ts", "gen-k8s-client": "npx @kubekit/codegen gen-config/k8s-client.ts", "cli": "lib/bin/cli.js", diff --git a/packages/kubekit-prepare/src/bin/cli.ts b/packages/kubekit-prepare/src/bin/cli.ts index 5e78456b..4a156527 100755 --- a/packages/kubekit-prepare/src/bin/cli.ts +++ b/packages/kubekit-prepare/src/bin/cli.ts @@ -3,20 +3,21 @@ import program from 'commander' import * as path from 'path' import * as fs from 'fs/promises' -import { patchFunctions } from '../patchOpenApi' +import { enhancementFunctions } from '../utils/openapi/enhance' import merge from 'lodash.merge' import { OpenAPIV3 } from 'openapi-types' import { type ResourceRules, - inspectRules, + fetchAggregatedPermissions, mapResourceVerbToKubernetesAction, -} from '../getRules' -import { HttpMethods, assertNotNull } from '../lib' +} from '../utils/k8s/permissionsAggregator.ts' +import { HttpMethods } from '../utils/types' import { apiClient } from '@kubekit/client' -import { ConfigFile } from '../config' -import { readCoreV1NamespacedServiceAccount } from '../k8s-client' +import { ConfigFile } from '../utils/types' +import { readCoreV1NamespacedServiceAccount } from '../utils/k8s/client' import { cleanOpenAPISchema } from '../utils/openapi/removeUnusedSchema' import { prettify } from '../utils/openapi/prettier' +import { assertNotNull } from '../utils/assertNotNull' let ts = false try { @@ -88,7 +89,7 @@ async function generateOpenApi(config: ConfigFile) { }, rootOpenApiText, ] = await Promise.all([ - inspectRules(config.kind, config.name, config.namespace), + fetchAggregatedPermissions(config.kind, config.name, config.namespace), apiClient({ path: '/openapi/v3' }), ]) @@ -195,6 +196,9 @@ async function generateOpenApi(config: ConfigFile) { resultDoc.paths[path] = {} } const resultPathsObject = resultDoc.paths[path] + + // The assertNotNull is used here to satisfy TypeScript's type checking, + // even though resultPathsObject is always assigned above. assertNotNull(resultPathsObject) resultPathsObject[httpMethod] = sourceDoc.paths[path]?.[httpMethod] @@ -246,7 +250,7 @@ async function generateOpenApi(config: ConfigFile) { let mergedSwaggerFile = merge({}, ...docs) - for (const patchFunction of patchFunctions) { + for (const patchFunction of enhancementFunctions) { mergedSwaggerFile = patchFunction(mergedSwaggerFile) } diff --git a/packages/kubekit-prepare/src/index.ts b/packages/kubekit-prepare/src/index.ts index 07c9f2dd..294efd43 100644 --- a/packages/kubekit-prepare/src/index.ts +++ b/packages/kubekit-prepare/src/index.ts @@ -1 +1 @@ -export { type ConfigFile } from './config' +export { type ConfigFile } from './utils/types' diff --git a/packages/kubekit-prepare/src/patchOpenApi/applyPatch.ts b/packages/kubekit-prepare/src/patchOpenApi/applyPatch.ts deleted file mode 100644 index 29aefbe0..00000000 --- a/packages/kubekit-prepare/src/patchOpenApi/applyPatch.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { OpenAPIV3 } from 'openapi-types' - -export function patchApplyPatch(doc: OpenAPIV3.Document) { - if (!doc.components?.schemas) { - doc.components = { schemas: {} } - } - - for (const path in doc.paths) { - if (path.endsWith('/status')) { - continue - } - const applyPatchRequestBody = ( - doc.paths[path]?.patch?.requestBody as OpenAPIV3.RequestBodyObject - )?.content['application/apply-patch+yaml'] - - if (!applyPatchRequestBody?.schema) { - continue - } - function getKind() { - if ( - applyPatchRequestBody.schema && - '$ref' in applyPatchRequestBody.schema - ) { - // a = "#/components/schemas/io.k8s.api.core.v1.ConfigMap" - const a = applyPatchRequestBody.schema.$ref.split('/') - // b = "io.k8s.api.core.v1.ConfigMap" - const b = a[a.length - 1] - const c = b.split('.') - // ConfigMap - return c[c.length - 1] - } - } - const kind = getKind() - const words = path.split('/') - const isCore = words.length <= 7 - if (words[2] && words[3] && kind) { - applyPatchRequestBody.schema = { - allOf: [ - applyPatchRequestBody.schema, - { - type: 'object', - properties: { - apiVersion: { - type: 'string', - enum: [isCore ? words[2] : `${words[2]}/${words[3]}`], - }, - kind: { - type: 'string', - ...(kind - ? { - enum: [kind], - } - : {}), - }, - }, - required: ['apiVersion', 'kind'], - }, - ], - } - } else { - throw Error(`impossible path: ${path}`) - } - } - - return doc -} diff --git a/packages/kubekit-prepare/src/patchOpenApi/gvk.ts b/packages/kubekit-prepare/src/patchOpenApi/gvk.ts deleted file mode 100644 index 18afdcc1..00000000 --- a/packages/kubekit-prepare/src/patchOpenApi/gvk.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { OpenAPIV3 } from 'openapi-types' - -export function patchGvk(doc: OpenAPIV3.Document) { - if (!doc.components?.schemas) { - return doc - } - - for (const schemaName in doc.components.schemas) { - const words = schemaName.split('.') - const schema = doc.components.schemas[schemaName] - if ( - 'properties' in schema && - schema.properties && - schema.properties['kind'] && - 'type' in schema.properties['kind'] && - schema.properties['apiVersion'] && - 'type' in schema.properties['apiVersion'] && - schema.properties['metadata'] - ) { - if (schema.properties['items']) { - schema.properties['kind'].enum = ['List'] - schema.properties['apiVersion'].enum = ['v1'] - schema.required = ['kind', 'apiVersion', 'metadata', 'items'] - } else if (words[words.length - 1]) { - schema.properties['kind'].enum = [words[words.length - 1]] - // "dev.knative.serving.v1.Service" - // "io.k8s.api.core.v1.Pod" - function getApiVersion() { - if (schemaName.startsWith('io.k8s.api.core.')) { - return words[words.length - 2] - } - - const [first, ...center] = words - center.pop() - const last = center.pop() - return `${center.join('.')}.${first}/${last}` - } - schema.properties['apiVersion'].enum = [getApiVersion()] - } - } - } - - return doc -} diff --git a/packages/kubekit-prepare/src/patchOpenApi/index.ts b/packages/kubekit-prepare/src/patchOpenApi/index.ts deleted file mode 100644 index 490cfc61..00000000 --- a/packages/kubekit-prepare/src/patchOpenApi/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { OpenAPIV3 } from 'openapi-types' -import { patchOp } from './op' -import { patchApplyPatch } from './applyPatch' -import { patchGvk } from './gvk' - -export const patchFunctions = [ - patchOp, - patchApplyPatch, - patchGvk, -] satisfies Array<(doc: OpenAPIV3.Document) => OpenAPIV3.Document> diff --git a/packages/kubekit-prepare/src/patchOpenApi/op.ts b/packages/kubekit-prepare/src/patchOpenApi/op.ts deleted file mode 100644 index 3fc3a1b1..00000000 --- a/packages/kubekit-prepare/src/patchOpenApi/op.ts +++ /dev/null @@ -1,195 +0,0 @@ -import type { OpenAPIV3 } from 'openapi-types' - -export function patchOp(doc: OpenAPIV3.Document) { - if (!doc.components?.schemas) { - doc.components = { schemas: {} } - } - let hasJsonPatch = false - - for (const path in doc.paths) { - const putContent = ( - doc.paths[path]?.put?.requestBody as OpenAPIV3.RequestBodyObject - )?.content - const putRequestBody = - putContent?.['*/*'] || - putContent?.['application/json'] || - putContent?.['application/yaml'] - if (!putRequestBody) { - continue - } - const applyPatchRequestBody = ( - doc.paths[path]?.patch?.requestBody as OpenAPIV3.RequestBodyObject - )?.content['application/apply-patch+yaml'] - - if (applyPatchRequestBody) { - applyPatchRequestBody.schema = putRequestBody.schema - } - - const strategicMergePatchRequestBody = ( - doc.paths[path]?.patch?.requestBody as OpenAPIV3.RequestBodyObject - )?.content['application/strategic-merge-patch+json'] - if (strategicMergePatchRequestBody) { - strategicMergePatchRequestBody.schema = putRequestBody.schema - } - - const mergePatchRequestBody = ( - doc.paths[path]?.patch?.requestBody as OpenAPIV3.RequestBodyObject - )?.content['application/merge-patch+json'] - if (mergePatchRequestBody) { - mergePatchRequestBody.schema = putRequestBody.schema - } - - const jsonPatchRequestBody = ( - doc.paths[path]?.patch?.requestBody as OpenAPIV3.RequestBodyObject - )?.content['application/json-patch+json'] - if (jsonPatchRequestBody) { - jsonPatchRequestBody.schema = { - $ref: '#/components/schemas/JsonPatchOperations', - } - hasJsonPatch = true - } - } - - if (hasJsonPatch) { - if (doc.components.schemas) { - const value = { - oneOf: [ - { - type: 'string', - }, - { - type: 'number', - }, - { - type: 'boolean', - }, - { - type: 'array', - }, - { - type: 'object', - }, - ], - } - - doc.components.schemas['JsonPatchOperation'] = { - type: 'object', - oneOf: [ - { - $ref: '#/components/schemas/AddOperation', - }, - { - $ref: '#/components/schemas/RemoveOperation', - }, - { - $ref: '#/components/schemas/ReplaceOperation', - }, - { - $ref: '#/components/schemas/MoveOperation', - }, - { - $ref: '#/components/schemas/CopyOperation', - }, - { - $ref: '#/components/schemas/TestOperation', - }, - ], - } - doc.components.schemas['AddOperation'] = { - type: 'object', - required: ['op', 'path', 'value'], - properties: { - op: { - type: 'string', - enum: ['add'], - }, - path: { - type: 'string', - }, - value: value as any, - }, - } - doc.components.schemas['RemoveOperation'] = { - type: 'object', - required: ['op', 'path'], - properties: { - op: { - type: 'string', - enum: ['remove'], - }, - path: { - type: 'string', - }, - }, - } - doc.components.schemas['ReplaceOperation'] = { - type: 'object', - required: ['op', 'path', 'value'], - properties: { - op: { - type: 'string', - enum: ['replace'], - }, - path: { - type: 'string', - }, - value: value as any, - }, - } - doc.components.schemas['MoveOperation'] = { - type: 'object', - required: ['op', 'path', 'from'], - properties: { - op: { - type: 'string', - enum: ['move'], - }, - path: { - type: 'string', - }, - from: { - type: 'string', - }, - }, - } - doc.components.schemas['CopyOperation'] = { - type: 'object', - required: ['op', 'path', 'from'], - properties: { - op: { - type: 'string', - enum: ['copy'], - }, - path: { - type: 'string', - }, - from: { - type: 'string', - }, - }, - } - doc.components.schemas['TestOperation'] = { - type: 'object', - required: ['op', 'path', 'value'], - properties: { - op: { - type: 'string', - enum: ['test'], - }, - path: { - type: 'string', - }, - value: value as any, - }, - } - doc.components.schemas['JsonPatchOperations'] = { - type: 'array', - items: { - $ref: '#/components/schemas/JsonPatchOperation', - }, - } - } - } - - return doc -} diff --git a/packages/kubekit-prepare/src/lib.ts b/packages/kubekit-prepare/src/utils/assertNotNull.ts similarity index 55% rename from packages/kubekit-prepare/src/lib.ts rename to packages/kubekit-prepare/src/utils/assertNotNull.ts index 93894e9e..9cc86618 100644 --- a/packages/kubekit-prepare/src/lib.ts +++ b/packages/kubekit-prepare/src/utils/assertNotNull.ts @@ -1,15 +1,5 @@ -export type HttpMethods = - | 'get' - | 'put' - | 'post' - | 'delete' - | 'options' - | 'head' - | 'patch' - | 'trace' - export function assertNotNull( - value: T | null | undefined, + value: T | null | undefined ): asserts value is NonNullable { if (value === null || value === undefined) { throw new Error('Assertion failed: value is null or undefined') diff --git a/packages/kubekit-prepare/src/utils/k8s/client.ts b/packages/kubekit-prepare/src/utils/k8s/client.ts new file mode 100644 index 00000000..181ed924 --- /dev/null +++ b/packages/kubekit-prepare/src/utils/k8s/client.ts @@ -0,0 +1,800 @@ +import { + apiClient, + type Options, + type WatchExtraOptions, +} from '@kubekit/client' +type Id = { + [K in keyof T]: T[K] +} & {} +type NoWatch = Omit & { + watch?: false +} +type RequiredAndDefined = { + [P in keyof T]-?: Exclude +} +type PartialRequired = Id< + RequiredAndDefined> & Omit +> +type MinimumRequiredGet = Id< + T extends { + metadata?: any + apiVersion?: any + kind?: any + } + ? Omit< + PartialRequired, + 'metadata' + > & { + metadata: PartialRequired< + RequiredAndDefined['metadata'], + 'name' | 'namespace' | 'creationTimestamp' | 'resourceVersion' + > + } + : T +> +type MinimumRequiredList = Id< + T extends { + items: { + metadata?: any + apiVersion?: any + kind?: any + }[] + } + ? Omit & { + items: MinimumRequiredGet[] + } + : T +> +export const readCoreV1NamespacedServiceAccount = ( + args: ReadCoreV1NamespacedServiceAccountApiArg, + options?: Options +) => { + return apiClient< + MinimumRequiredGet + >( + { + path: `/api/v1/namespaces/${args['namespace']}/serviceaccounts/${args.name}`, + params: { pretty: args.pretty }, + }, + options + ) +} +export function listRbacAuthorizationV1ClusterRoleBinding( + args: NoWatch, + options?: Options +): Promise< + MinimumRequiredList +> +export function listRbacAuthorizationV1ClusterRoleBinding( + args: ListRbacAuthorizationV1ClusterRoleBindingApiArg & { + watch: true + }, + options: Options & + WatchExtraOptions< + MinimumRequiredList + > +): Promise +export function listRbacAuthorizationV1ClusterRoleBinding( + args: any, + options: any +): any { + return apiClient< + MinimumRequiredList + >( + { + path: `/apis/rbac.authorization.k8s.io/v1/clusterrolebindings`, + params: { + pretty: args.pretty, + allowWatchBookmarks: args.allowWatchBookmarks, + continue: args['continue'], + fieldSelector: args.fieldSelector, + labelSelector: args.labelSelector, + limit: args.limit, + resourceVersion: args.resourceVersion, + resourceVersionMatch: args.resourceVersionMatch, + sendInitialEvents: args.sendInitialEvents, + timeoutSeconds: args.timeoutSeconds, + watch: args.watch, + }, + }, + options + ) +} +export function listRbacAuthorizationV1ClusterRole( + args: NoWatch, + options?: Options +): Promise> +export function listRbacAuthorizationV1ClusterRole( + args: ListRbacAuthorizationV1ClusterRoleApiArg & { + watch: true + }, + options: Options & + WatchExtraOptions< + MinimumRequiredList + > +): Promise +export function listRbacAuthorizationV1ClusterRole( + args: any, + options: any +): any { + return apiClient< + MinimumRequiredList + >( + { + path: `/apis/rbac.authorization.k8s.io/v1/clusterroles`, + params: { + pretty: args.pretty, + allowWatchBookmarks: args.allowWatchBookmarks, + continue: args['continue'], + fieldSelector: args.fieldSelector, + labelSelector: args.labelSelector, + limit: args.limit, + resourceVersion: args.resourceVersion, + resourceVersionMatch: args.resourceVersionMatch, + sendInitialEvents: args.sendInitialEvents, + timeoutSeconds: args.timeoutSeconds, + watch: args.watch, + }, + }, + options + ) +} +export const readRbacAuthorizationV1ClusterRole = ( + args: ReadRbacAuthorizationV1ClusterRoleApiArg, + options?: Options +) => { + return apiClient< + MinimumRequiredGet + >( + { + path: `/apis/rbac.authorization.k8s.io/v1/clusterroles/${args.name}`, + params: { pretty: args.pretty }, + }, + options + ) +} +export function listRbacAuthorizationV1NamespacedRoleBinding( + args: NoWatch, + options?: Options +): Promise< + MinimumRequiredList +> +export function listRbacAuthorizationV1NamespacedRoleBinding( + args: ListRbacAuthorizationV1NamespacedRoleBindingApiArg & { + watch: true + }, + options: Options & + WatchExtraOptions< + MinimumRequiredList + > +): Promise +export function listRbacAuthorizationV1NamespacedRoleBinding( + args: any, + options: any +): any { + return apiClient< + MinimumRequiredList + >( + { + path: `/apis/rbac.authorization.k8s.io/v1/namespaces/${args['namespace']}/rolebindings`, + params: { + pretty: args.pretty, + allowWatchBookmarks: args.allowWatchBookmarks, + continue: args['continue'], + fieldSelector: args.fieldSelector, + labelSelector: args.labelSelector, + limit: args.limit, + resourceVersion: args.resourceVersion, + resourceVersionMatch: args.resourceVersionMatch, + sendInitialEvents: args.sendInitialEvents, + timeoutSeconds: args.timeoutSeconds, + watch: args.watch, + }, + }, + options + ) +} +export function listRbacAuthorizationV1NamespacedRole( + args: NoWatch, + options?: Options +): Promise< + MinimumRequiredList +> +export function listRbacAuthorizationV1NamespacedRole( + args: ListRbacAuthorizationV1NamespacedRoleApiArg & { + watch: true + }, + options: Options & + WatchExtraOptions< + MinimumRequiredList + > +): Promise +export function listRbacAuthorizationV1NamespacedRole( + args: any, + options: any +): any { + return apiClient< + MinimumRequiredList + >( + { + path: `/apis/rbac.authorization.k8s.io/v1/namespaces/${args['namespace']}/roles`, + params: { + pretty: args.pretty, + allowWatchBookmarks: args.allowWatchBookmarks, + continue: args['continue'], + fieldSelector: args.fieldSelector, + labelSelector: args.labelSelector, + limit: args.limit, + resourceVersion: args.resourceVersion, + resourceVersionMatch: args.resourceVersionMatch, + sendInitialEvents: args.sendInitialEvents, + timeoutSeconds: args.timeoutSeconds, + watch: args.watch, + }, + }, + options + ) +} +export const readRbacAuthorizationV1NamespacedRole = ( + args: ReadRbacAuthorizationV1NamespacedRoleApiArg, + options?: Options +) => { + return apiClient< + MinimumRequiredGet + >( + { + path: `/apis/rbac.authorization.k8s.io/v1/namespaces/${args['namespace']}/roles/${args.name}`, + params: { pretty: args.pretty }, + }, + options + ) +} +export function listRbacAuthorizationV1RoleBindingForAllNamespaces( + args: NoWatch, + options?: Options +): Promise< + MinimumRequiredList +> +export function listRbacAuthorizationV1RoleBindingForAllNamespaces( + args: ListRbacAuthorizationV1RoleBindingForAllNamespacesApiArg & { + watch: true + }, + options: Options & + WatchExtraOptions< + MinimumRequiredList + > +): Promise +export function listRbacAuthorizationV1RoleBindingForAllNamespaces( + args: any, + options: any +): any { + return apiClient< + MinimumRequiredList + >( + { + path: `/apis/rbac.authorization.k8s.io/v1/rolebindings`, + params: { + allowWatchBookmarks: args.allowWatchBookmarks, + continue: args['continue'], + fieldSelector: args.fieldSelector, + labelSelector: args.labelSelector, + limit: args.limit, + pretty: args.pretty, + resourceVersion: args.resourceVersion, + resourceVersionMatch: args.resourceVersionMatch, + sendInitialEvents: args.sendInitialEvents, + timeoutSeconds: args.timeoutSeconds, + watch: args.watch, + }, + }, + options + ) +} +export function listRbacAuthorizationV1RoleForAllNamespaces( + args: NoWatch, + options?: Options +): Promise< + MinimumRequiredList +> +export function listRbacAuthorizationV1RoleForAllNamespaces( + args: ListRbacAuthorizationV1RoleForAllNamespacesApiArg & { + watch: true + }, + options: Options & + WatchExtraOptions< + MinimumRequiredList + > +): Promise +export function listRbacAuthorizationV1RoleForAllNamespaces( + args: any, + options: any +): any { + return apiClient< + MinimumRequiredList + >( + { + path: `/apis/rbac.authorization.k8s.io/v1/roles`, + params: { + allowWatchBookmarks: args.allowWatchBookmarks, + continue: args['continue'], + fieldSelector: args.fieldSelector, + labelSelector: args.labelSelector, + limit: args.limit, + pretty: args.pretty, + resourceVersion: args.resourceVersion, + resourceVersionMatch: args.resourceVersionMatch, + sendInitialEvents: args.sendInitialEvents, + timeoutSeconds: args.timeoutSeconds, + watch: args.watch, + }, + }, + options + ) +} +export type ReadCoreV1NamespacedServiceAccountApiResponse = + /** status 200 OK */ IoK8SApiCoreV1ServiceAccount +export type ReadCoreV1NamespacedServiceAccountApiArg = { + /** name of the ServiceAccount */ + name: string + /** object name and auth scope, such as for teams and projects */ + namespace: string + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string +} +export type ListRbacAuthorizationV1ClusterRoleBindingApiResponse = + /** status 200 OK */ IoK8SApiRbacV1ClusterRoleBindingList +export type ListRbacAuthorizationV1ClusterRoleBindingApiArg = { + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string + /** allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. */ + allowWatchBookmarks?: boolean + /** The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + + This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. */ + continue?: string + /** A selector to restrict the list of returned objects by their fields. Defaults to everything. */ + fieldSelector?: string + /** A selector to restrict the list of returned objects by their labels. Defaults to everything. */ + labelSelector?: string + /** limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + + The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. */ + limit?: number + /** resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersion?: string + /** resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersionMatch?: string + /** `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic "Bookmark" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. + + When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan + is interpreted as "data at least as new as the provided `resourceVersion`" + and the bookmark event is send when the state is synced + to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + If `resourceVersion` is unset, this is interpreted as "consistent read" and the + bookmark event is send when the state is synced at least to the moment + when request started being processed. + - `resourceVersionMatch` set to any other value or unset + Invalid error is returned. + + Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward compatibility reasons) and to false otherwise. */ + sendInitialEvents?: boolean + /** Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. */ + timeoutSeconds?: number + /** Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. */ + watch?: boolean +} +export type ListRbacAuthorizationV1ClusterRoleApiResponse = + /** status 200 OK */ IoK8SApiRbacV1ClusterRoleList +export type ListRbacAuthorizationV1ClusterRoleApiArg = { + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string + /** allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. */ + allowWatchBookmarks?: boolean + /** The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + + This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. */ + continue?: string + /** A selector to restrict the list of returned objects by their fields. Defaults to everything. */ + fieldSelector?: string + /** A selector to restrict the list of returned objects by their labels. Defaults to everything. */ + labelSelector?: string + /** limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + + The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. */ + limit?: number + /** resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersion?: string + /** resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersionMatch?: string + /** `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic "Bookmark" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. + + When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan + is interpreted as "data at least as new as the provided `resourceVersion`" + and the bookmark event is send when the state is synced + to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + If `resourceVersion` is unset, this is interpreted as "consistent read" and the + bookmark event is send when the state is synced at least to the moment + when request started being processed. + - `resourceVersionMatch` set to any other value or unset + Invalid error is returned. + + Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward compatibility reasons) and to false otherwise. */ + sendInitialEvents?: boolean + /** Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. */ + timeoutSeconds?: number + /** Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. */ + watch?: boolean +} +export type ReadRbacAuthorizationV1ClusterRoleApiResponse = + /** status 200 OK */ IoK8SApiRbacV1ClusterRole +export type ReadRbacAuthorizationV1ClusterRoleApiArg = { + /** name of the ClusterRole */ + name: string + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string +} +export type ListRbacAuthorizationV1NamespacedRoleBindingApiResponse = + /** status 200 OK */ IoK8SApiRbacV1RoleBindingList +export type ListRbacAuthorizationV1NamespacedRoleBindingApiArg = { + /** object name and auth scope, such as for teams and projects */ + namespace: string + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string + /** allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. */ + allowWatchBookmarks?: boolean + /** The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + + This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. */ + continue?: string + /** A selector to restrict the list of returned objects by their fields. Defaults to everything. */ + fieldSelector?: string + /** A selector to restrict the list of returned objects by their labels. Defaults to everything. */ + labelSelector?: string + /** limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + + The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. */ + limit?: number + /** resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersion?: string + /** resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersionMatch?: string + /** `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic "Bookmark" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. + + When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan + is interpreted as "data at least as new as the provided `resourceVersion`" + and the bookmark event is send when the state is synced + to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + If `resourceVersion` is unset, this is interpreted as "consistent read" and the + bookmark event is send when the state is synced at least to the moment + when request started being processed. + - `resourceVersionMatch` set to any other value or unset + Invalid error is returned. + + Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward compatibility reasons) and to false otherwise. */ + sendInitialEvents?: boolean + /** Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. */ + timeoutSeconds?: number + /** Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. */ + watch?: boolean +} +export type ListRbacAuthorizationV1NamespacedRoleApiResponse = + /** status 200 OK */ IoK8SApiRbacV1RoleList +export type ListRbacAuthorizationV1NamespacedRoleApiArg = { + /** object name and auth scope, such as for teams and projects */ + namespace: string + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string + /** allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. */ + allowWatchBookmarks?: boolean + /** The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + + This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. */ + continue?: string + /** A selector to restrict the list of returned objects by their fields. Defaults to everything. */ + fieldSelector?: string + /** A selector to restrict the list of returned objects by their labels. Defaults to everything. */ + labelSelector?: string + /** limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + + The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. */ + limit?: number + /** resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersion?: string + /** resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersionMatch?: string + /** `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic "Bookmark" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. + + When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan + is interpreted as "data at least as new as the provided `resourceVersion`" + and the bookmark event is send when the state is synced + to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + If `resourceVersion` is unset, this is interpreted as "consistent read" and the + bookmark event is send when the state is synced at least to the moment + when request started being processed. + - `resourceVersionMatch` set to any other value or unset + Invalid error is returned. + + Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward compatibility reasons) and to false otherwise. */ + sendInitialEvents?: boolean + /** Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. */ + timeoutSeconds?: number + /** Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. */ + watch?: boolean +} +export type ReadRbacAuthorizationV1NamespacedRoleApiResponse = + /** status 200 OK */ IoK8SApiRbacV1Role +export type ReadRbacAuthorizationV1NamespacedRoleApiArg = { + /** name of the Role */ + name: string + /** object name and auth scope, such as for teams and projects */ + namespace: string + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string +} +export type ListRbacAuthorizationV1RoleBindingForAllNamespacesApiResponse = + /** status 200 OK */ IoK8SApiRbacV1RoleBindingList +export type ListRbacAuthorizationV1RoleBindingForAllNamespacesApiArg = { + /** allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. */ + allowWatchBookmarks?: boolean + /** The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + + This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. */ + continue?: string + /** A selector to restrict the list of returned objects by their fields. Defaults to everything. */ + fieldSelector?: string + /** A selector to restrict the list of returned objects by their labels. Defaults to everything. */ + labelSelector?: string + /** limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + + The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. */ + limit?: number + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string + /** resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersion?: string + /** resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersionMatch?: string + /** `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic "Bookmark" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. + + When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan + is interpreted as "data at least as new as the provided `resourceVersion`" + and the bookmark event is send when the state is synced + to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + If `resourceVersion` is unset, this is interpreted as "consistent read" and the + bookmark event is send when the state is synced at least to the moment + when request started being processed. + - `resourceVersionMatch` set to any other value or unset + Invalid error is returned. + + Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward compatibility reasons) and to false otherwise. */ + sendInitialEvents?: boolean + /** Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. */ + timeoutSeconds?: number + /** Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. */ + watch?: boolean +} +export type ListRbacAuthorizationV1RoleForAllNamespacesApiResponse = + /** status 200 OK */ IoK8SApiRbacV1RoleList +export type ListRbacAuthorizationV1RoleForAllNamespacesApiArg = { + /** allowWatchBookmarks requests watch events with type "BOOKMARK". Servers that do not implement bookmarks may ignore this flag and bookmarks are sent at the server's discretion. Clients should not assume bookmarks are returned at any specific interval, nor may they assume the server will send any BOOKMARK event during a session. If this is not a watch, this field is ignored. */ + allowWatchBookmarks?: boolean + /** The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the "next key". + + This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. */ + continue?: string + /** A selector to restrict the list of returned objects by their fields. Defaults to everything. */ + fieldSelector?: string + /** A selector to restrict the list of returned objects by their labels. Defaults to everything. */ + labelSelector?: string + /** limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. + + The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. */ + limit?: number + /** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */ + pretty?: string + /** resourceVersion sets a constraint on what resource versions a request may be served from. See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersion?: string + /** resourceVersionMatch determines how resourceVersion is applied to list calls. It is highly recommended that resourceVersionMatch be set for list calls where resourceVersion is set See https://kubernetes.io/docs/reference/using-api/api-concepts/#resource-versions for details. + + Defaults to unset */ + resourceVersionMatch?: string + /** `sendInitialEvents=true` may be set together with `watch=true`. In that case, the watch stream will begin with synthetic events to produce the current state of objects in the collection. Once all such events have been sent, a synthetic "Bookmark" event will be sent. The bookmark will report the ResourceVersion (RV) corresponding to the set of objects, and be marked with `"k8s.io/initial-events-end": "true"` annotation. Afterwards, the watch stream will proceed as usual, sending watch events corresponding to changes (subsequent to the RV) to objects watched. + + When `sendInitialEvents` option is set, we require `resourceVersionMatch` option to also be set. The semantic of the watch request is as following: - `resourceVersionMatch` = NotOlderThan + is interpreted as "data at least as new as the provided `resourceVersion`" + and the bookmark event is send when the state is synced + to a `resourceVersion` at least as fresh as the one provided by the ListOptions. + If `resourceVersion` is unset, this is interpreted as "consistent read" and the + bookmark event is send when the state is synced at least to the moment + when request started being processed. + - `resourceVersionMatch` set to any other value or unset + Invalid error is returned. + + Defaults to true if `resourceVersion=""` or `resourceVersion="0"` (for backward compatibility reasons) and to false otherwise. */ + sendInitialEvents?: boolean + /** Timeout for the list/watch call. This limits the duration of the call, regardless of any activity or inactivity. */ + timeoutSeconds?: number + /** Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. */ + watch?: boolean +} +export type IoK8SApiCoreV1LocalObjectReference = { + name?: string | undefined +} +export type IoK8SApimachineryPkgApisMetaV1Time = string +export type IoK8SApimachineryPkgApisMetaV1FieldsV1 = object +export type IoK8SApimachineryPkgApisMetaV1ManagedFieldsEntry = { + apiVersion?: string | undefined + fieldsType?: string | undefined + fieldsV1?: IoK8SApimachineryPkgApisMetaV1FieldsV1 | undefined + manager?: string | undefined + operation?: string | undefined + subresource?: string | undefined + time?: IoK8SApimachineryPkgApisMetaV1Time | undefined +} +export type IoK8SApimachineryPkgApisMetaV1OwnerReference = { + apiVersion: string + blockOwnerDeletion?: boolean | undefined + controller?: boolean | undefined + kind: string + name: string + uid: string +} +export type IoK8SApimachineryPkgApisMetaV1ObjectMeta = { + annotations?: + | { + [key: string]: string + } + | undefined + creationTimestamp?: IoK8SApimachineryPkgApisMetaV1Time | undefined + deletionGracePeriodSeconds?: number | undefined + deletionTimestamp?: IoK8SApimachineryPkgApisMetaV1Time | undefined + finalizers?: string[] | undefined + generateName?: string | undefined + generation?: number | undefined + labels?: + | { + [key: string]: string + } + | undefined + managedFields?: IoK8SApimachineryPkgApisMetaV1ManagedFieldsEntry[] | undefined + name?: string | undefined + namespace?: string | undefined + ownerReferences?: IoK8SApimachineryPkgApisMetaV1OwnerReference[] | undefined + resourceVersion?: string | undefined + selfLink?: string | undefined + uid?: string | undefined +} +export type IoK8SApiCoreV1ObjectReference = { + apiVersion?: string | undefined + fieldPath?: string | undefined + kind?: string | undefined + name?: string | undefined + namespace?: string | undefined + resourceVersion?: string | undefined + uid?: string | undefined +} +export type IoK8SApiCoreV1ServiceAccount = { + apiVersion?: 'v1' | undefined + automountServiceAccountToken?: boolean | undefined + imagePullSecrets?: IoK8SApiCoreV1LocalObjectReference[] | undefined + kind?: 'ServiceAccount' | undefined + metadata?: IoK8SApimachineryPkgApisMetaV1ObjectMeta | undefined + secrets?: IoK8SApiCoreV1ObjectReference[] | undefined +} +export type IoK8SApiRbacV1RoleRef = { + apiGroup: string + kind: string + name: string +} +export type IoK8SApiRbacV1Subject = { + apiGroup?: string | undefined + kind: string + name: string + namespace?: string | undefined +} +export type IoK8SApiRbacV1ClusterRoleBinding = { + apiVersion?: 'k8s.api.rbac.io/v1' | undefined + kind?: 'ClusterRoleBinding' | undefined + metadata?: IoK8SApimachineryPkgApisMetaV1ObjectMeta | undefined + roleRef: IoK8SApiRbacV1RoleRef + subjects?: IoK8SApiRbacV1Subject[] | undefined +} +export type IoK8SApimachineryPkgApisMetaV1ListMeta = { + continue?: string | undefined + remainingItemCount?: number | undefined + resourceVersion?: string | undefined + selfLink?: string | undefined +} +export type IoK8SApiRbacV1ClusterRoleBindingList = { + apiVersion: 'v1' + items: IoK8SApiRbacV1ClusterRoleBinding[] + kind: 'List' + metadata: IoK8SApimachineryPkgApisMetaV1ListMeta +} +export type IoK8SApimachineryPkgApisMetaV1LabelSelectorRequirement = { + key: string + operator: string + values?: string[] | undefined +} +export type IoK8SApimachineryPkgApisMetaV1LabelSelector = { + matchExpressions?: + | IoK8SApimachineryPkgApisMetaV1LabelSelectorRequirement[] + | undefined + matchLabels?: + | { + [key: string]: string + } + | undefined +} +export type IoK8SApiRbacV1AggregationRule = { + clusterRoleSelectors?: + | IoK8SApimachineryPkgApisMetaV1LabelSelector[] + | undefined +} +export type IoK8SApiRbacV1PolicyRule = { + apiGroups?: string[] | undefined + nonResourceURLs?: string[] | undefined + resourceNames?: string[] | undefined + resources?: string[] | undefined + verbs: string[] +} +export type IoK8SApiRbacV1ClusterRole = { + aggregationRule?: IoK8SApiRbacV1AggregationRule | undefined + apiVersion?: 'k8s.api.rbac.io/v1' | undefined + kind?: 'ClusterRole' | undefined + metadata?: IoK8SApimachineryPkgApisMetaV1ObjectMeta | undefined + rules?: IoK8SApiRbacV1PolicyRule[] | undefined +} +export type IoK8SApiRbacV1ClusterRoleList = { + apiVersion: 'v1' + items: IoK8SApiRbacV1ClusterRole[] + kind: 'List' + metadata: IoK8SApimachineryPkgApisMetaV1ListMeta +} +export type IoK8SApiRbacV1RoleBinding = { + apiVersion?: 'k8s.api.rbac.io/v1' | undefined + kind?: 'RoleBinding' | undefined + metadata?: IoK8SApimachineryPkgApisMetaV1ObjectMeta | undefined + roleRef: IoK8SApiRbacV1RoleRef + subjects?: IoK8SApiRbacV1Subject[] | undefined +} +export type IoK8SApiRbacV1RoleBindingList = { + apiVersion: 'v1' + items: IoK8SApiRbacV1RoleBinding[] + kind: 'List' + metadata: IoK8SApimachineryPkgApisMetaV1ListMeta +} +export type IoK8SApiRbacV1Role = { + apiVersion?: 'k8s.api.rbac.io/v1' | undefined + kind?: 'Role' | undefined + metadata?: IoK8SApimachineryPkgApisMetaV1ObjectMeta | undefined + rules?: IoK8SApiRbacV1PolicyRule[] | undefined +} +export type IoK8SApiRbacV1RoleList = { + apiVersion: 'v1' + items: IoK8SApiRbacV1Role[] + kind: 'List' + metadata: IoK8SApimachineryPkgApisMetaV1ListMeta +} diff --git a/packages/kubekit-prepare/src/getRules.ts b/packages/kubekit-prepare/src/utils/k8s/permissionsAggregator.ts.ts similarity index 94% rename from packages/kubekit-prepare/src/getRules.ts rename to packages/kubekit-prepare/src/utils/k8s/permissionsAggregator.ts.ts index 592591c3..c8aaed94 100644 --- a/packages/kubekit-prepare/src/getRules.ts +++ b/packages/kubekit-prepare/src/utils/k8s/permissionsAggregator.ts.ts @@ -6,11 +6,11 @@ import { listRbacAuthorizationV1RoleBindingForAllNamespaces, readRbacAuthorizationV1ClusterRole, readRbacAuthorizationV1NamespacedRole, -} from './k8s-client' +} from './client' type Url = string -export async function inspectRules( +export async function fetchAggregatedPermissions( kind: string, name: string, namespace: string @@ -18,10 +18,10 @@ export async function inspectRules( const resourceRules = {} as ResourceRules const nonResourceRules = {} as NonResourceRules - const roles = await getRoles(kind, name, namespace) + const roles = await fetchRoles(kind, name, namespace) mutateDict(roles, resourceRules, nonResourceRules) - const clusterRoles = await getClusterRoles(kind, name, namespace) + const clusterRoles = await fetchClusterRoles(kind, name, namespace) mutateDict(clusterRoles, resourceRules, nonResourceRules) return { @@ -30,7 +30,7 @@ export async function inspectRules( } } -async function getRoles(kind: string, name: string, namespace: string) { +async function fetchRoles(kind: string, name: string, namespace: string) { const roleBindings = await listRbacAuthorizationV1RoleBindingForAllNamespaces( {} ) @@ -81,7 +81,11 @@ async function getRoles(kind: string, name: string, namespace: string) { } // TODO: Support aggregationRule -async function getClusterRoles(kind: string, name: string, namespace: string) { +async function fetchClusterRoles( + kind: string, + name: string, + namespace: string +) { const clusterRoleBindings = await listRbacAuthorizationV1ClusterRoleBinding( {} ) diff --git a/packages/kubekit-prepare/src/config.ts b/packages/kubekit-prepare/src/utils/types.ts similarity index 51% rename from packages/kubekit-prepare/src/config.ts rename to packages/kubekit-prepare/src/utils/types.ts index 283a9e84..4419e103 100644 --- a/packages/kubekit-prepare/src/config.ts +++ b/packages/kubekit-prepare/src/utils/types.ts @@ -1,3 +1,13 @@ +export type HttpMethods = + | 'get' + | 'put' + | 'post' + | 'delete' + | 'options' + | 'head' + | 'patch' + | 'trace' + export type ConfigFile = { kind: 'ServiceAccount' | 'User' | 'Group' name: string diff --git a/packages/kubekit-prepare/tests/test3.openapi.json b/packages/kubekit-prepare/tests/test3.openapi.json index 63a7fa9b..ebcc0337 100644 --- a/packages/kubekit-prepare/tests/test3.openapi.json +++ b/packages/kubekit-prepare/tests/test3.openapi.json @@ -1830,6 +1830,231 @@ } } }, + "/api/v1/namespaces/{namespace}/pods/{name}/proxy/{path}": { + "delete": { + "description": "connect DELETE requests to proxy of Pod", + "operationId": "connectCoreV1DeleteNamespacedPodProxyWithPath", + "responses": { + "200": { + "content": { + "*/*": { + "schema": { + "type": "string" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": ["core_v1"], + "x-kubernetes-action": "connect", + "x-kubernetes-group-version-kind": { + "group": "", + "kind": "PodProxyOptions", + "version": "v1" + } + }, + "get": { + "description": "connect GET requests to proxy of Pod", + "operationId": "connectCoreV1GetNamespacedPodProxyWithPath", + "responses": { + "200": { + "content": { + "*/*": { + "schema": { + "type": "string" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": ["core_v1"], + "x-kubernetes-action": "connect", + "x-kubernetes-group-version-kind": { + "group": "", + "kind": "PodProxyOptions", + "version": "v1" + } + }, + "head": { + "description": "connect HEAD requests to proxy of Pod", + "operationId": "connectCoreV1HeadNamespacedPodProxyWithPath", + "responses": { + "200": { + "content": { + "*/*": { + "schema": { + "type": "string" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": ["core_v1"], + "x-kubernetes-action": "connect", + "x-kubernetes-group-version-kind": { + "group": "", + "kind": "PodProxyOptions", + "version": "v1" + } + }, + "options": { + "description": "connect OPTIONS requests to proxy of Pod", + "operationId": "connectCoreV1OptionsNamespacedPodProxyWithPath", + "responses": { + "200": { + "content": { + "*/*": { + "schema": { + "type": "string" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": ["core_v1"], + "x-kubernetes-action": "connect", + "x-kubernetes-group-version-kind": { + "group": "", + "kind": "PodProxyOptions", + "version": "v1" + } + }, + "parameters": [ + { + "description": "name of the PodProxyOptions", + "in": "path", + "name": "name", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "object name and auth scope, such as for teams and projects", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "path to the resource", + "in": "path", + "name": "path", + "required": true, + "schema": { + "type": "string", + "uniqueItems": true + } + }, + { + "description": "Path is the URL path to use for the current proxy request to pod.", + "in": "query", + "name": "path", + "schema": { + "type": "string", + "uniqueItems": true + } + } + ], + "patch": { + "description": "connect PATCH requests to proxy of Pod", + "operationId": "connectCoreV1PatchNamespacedPodProxyWithPath", + "responses": { + "200": { + "content": { + "*/*": { + "schema": { + "type": "string" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": ["core_v1"], + "x-kubernetes-action": "connect", + "x-kubernetes-group-version-kind": { + "group": "", + "kind": "PodProxyOptions", + "version": "v1" + } + }, + "post": { + "description": "connect POST requests to proxy of Pod", + "operationId": "connectCoreV1PostNamespacedPodProxyWithPath", + "responses": { + "200": { + "content": { + "*/*": { + "schema": { + "type": "string" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": ["core_v1"], + "x-kubernetes-action": "connect", + "x-kubernetes-group-version-kind": { + "group": "", + "kind": "PodProxyOptions", + "version": "v1" + } + }, + "put": { + "description": "connect PUT requests to proxy of Pod", + "operationId": "connectCoreV1PutNamespacedPodProxyWithPath", + "responses": { + "200": { + "content": { + "*/*": { + "schema": { + "type": "string" + } + } + }, + "description": "OK" + }, + "401": { + "description": "Unauthorized" + } + }, + "tags": ["core_v1"], + "x-kubernetes-action": "connect", + "x-kubernetes-group-version-kind": { + "group": "", + "kind": "PodProxyOptions", + "version": "v1" + } + } + }, "/api/v1/pods": { "get": { "description": "list or watch objects of kind Pod",