fix(api-docs) fix api spec and handler mismatches (#3104)

This commit is contained in:
Hannah Cooper
2026-07-20 11:10:12 +12:00
committed by GitHub
parent 2b7b8b492e
commit e465128e29
8 changed files with 433 additions and 51 deletions
+100 -9
View File
@@ -4839,7 +4839,7 @@ paths:
"/kubernetes/{id}/namespaces":
delete:
description: |-
Delete a kubernetes namespace within the given environment.
Delete one or more kubernetes namespaces within the given environment.
**Access policy**: Authenticated user.
operationId: DeleteKubernetesNamespace
parameters:
@@ -4849,6 +4849,15 @@ paths:
required: true
schema:
type: integer
requestBody:
content:
application/json:
schema:
items:
type: string
type: array
description: List of namespace names to delete
required: true
responses:
"200":
description: Success
@@ -4866,7 +4875,7 @@ paths:
security:
- ApiKeyAuth: []
jwt: []
summary: Delete a kubernetes namespace
summary: Delete kubernetes namespaces
tags:
- kubernetes
get:
@@ -4889,14 +4898,12 @@ paths:
the Namespace information. Default is false
in: query
name: withResourceQuota
required: true
schema:
type: boolean
- description: When set to true, include the unhealthy events information as part
of the Namespace information. Default is false
in: query
name: withUnhealthyEvents
required: true
schema:
type: boolean
responses:
@@ -4956,7 +4963,7 @@ paths:
content:
application/json:
schema:
$ref: "#/components/schemas/portainer.K8sNamespaceInfo"
$ref: "#/components/schemas/kubernetes.KubernetesCreateNamespaceResponse"
"400":
description: Invalid request payload, such as missing required fields or fields
not meeting validation criteria.
@@ -5054,7 +5061,6 @@ paths:
the Namespace information. Default is false
in: query
name: withResourceQuota
required: true
schema:
type: boolean
responses:
@@ -8589,7 +8595,7 @@ paths:
content:
application/json:
schema:
$ref: "#/components/schemas/portainer.Stack"
$ref: "#/components/schemas/stacks.createKubernetesStackResponse"
"400":
description: Invalid request
"409":
@@ -8630,7 +8636,7 @@ paths:
content:
application/json:
schema:
$ref: "#/components/schemas/portainer.Stack"
$ref: "#/components/schemas/stacks.createKubernetesStackResponse"
"400":
description: Invalid request
"500":
@@ -8669,7 +8675,7 @@ paths:
content:
application/json:
schema:
$ref: "#/components/schemas/portainer.Stack"
$ref: "#/components/schemas/stacks.createKubernetesStackResponse"
"400":
description: Invalid request
"500":
@@ -13240,6 +13246,64 @@ components:
storageClass:
$ref: "#/components/schemas/kubernetes.K8sStorageClass"
type: object
kubernetes.KubernetesCreateNamespaceResponse:
properties:
apiVersion:
description: >-
APIVersion defines the versioned schema of this representation of an
object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+optional
type: string
kind:
description: >-
Kind is a string value representing the REST resource this object
represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+optional
type: string
metadata:
allOf:
- $ref: "#/components/schemas/v1.ObjectMeta"
description: >-
Standard object's metadata.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
+optional
spec:
allOf:
- $ref: "#/components/schemas/v1.NamespaceSpec"
description: >-
Spec defines the behavior of the Namespace.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
+optional
status:
allOf:
- $ref: "#/components/schemas/v1.NamespaceStatus"
description: >-
Status describes the current status of a Namespace.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
+optional
type: object
kubernetes.KubernetesNodeResponse:
properties:
apiVersion:
@@ -16889,6 +16953,11 @@ components:
required:
- Name
type: object
stacks.createKubernetesStackResponse:
properties:
Output:
type: string
type: object
stacks.kubernetesGitDeploymentPayload:
properties:
AdditionalFiles:
@@ -18699,6 +18768,12 @@ components:
+required
type: string
type: object
v1.FinalizerName:
enum:
- kubernetes
type: string
x-enum-varnames:
- FinalizerKubernetes
v1.GRPCAction:
properties:
port:
@@ -19042,6 +19117,22 @@ components:
x-enum-varnames:
- NamespaceActive
- NamespaceTerminating
v1.NamespaceSpec:
properties:
finalizers:
description: >-
Finalizers is an opaque list of values that must be empty to
permanently remove object from storage.
More info: https://kubernetes.io/docs/tasks/administer-cluster/namespaces/
+optional
+listType=atomic
items:
$ref: "#/components/schemas/v1.FinalizerName"
type: array
type: object
v1.NamespaceStatus:
properties:
conditions:
+80 -9
View File
@@ -2342,6 +2342,47 @@ definitions:
storageClass:
$ref: '#/definitions/kubernetes.K8sStorageClass'
type: object
kubernetes.KubernetesCreateNamespaceResponse:
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+optional
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+optional
type: string
metadata:
allOf:
- $ref: '#/definitions/v1.ObjectMeta'
description: |-
Standard object's metadata.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
+optional
spec:
allOf:
- $ref: '#/definitions/v1.NamespaceSpec'
description: |-
Spec defines the behavior of the Namespace.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
+optional
status:
allOf:
- $ref: '#/definitions/v1.NamespaceStatus'
description: |-
Status describes the current status of a Namespace.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
+optional
type: object
kubernetes.KubernetesNodeResponse:
properties:
apiVersion:
@@ -5914,6 +5955,11 @@ definitions:
required:
- Name
type: object
stacks.createKubernetesStackResponse:
properties:
Output:
type: string
type: object
stacks.kubernetesGitDeploymentPayload:
properties:
AdditionalFiles:
@@ -7449,6 +7495,12 @@ definitions:
+required
type: string
type: object
v1.FinalizerName:
enum:
- kubernetes
type: string
x-enum-varnames:
- FinalizerKubernetes
v1.GRPCAction:
properties:
port:
@@ -7720,6 +7772,18 @@ definitions:
x-enum-varnames:
- NamespaceActive
- NamespaceTerminating
v1.NamespaceSpec:
properties:
finalizers:
description: |-
Finalizers is an opaque list of values that must be empty to permanently remove object from storage.
More info: https://kubernetes.io/docs/tasks/administer-cluster/namespaces/
+optional
+listType=atomic
items:
$ref: '#/definitions/v1.FinalizerName'
type: array
type: object
v1.NamespaceStatus:
properties:
conditions:
@@ -14326,8 +14390,10 @@ paths:
- kubernetes
/kubernetes/{id}/namespaces:
delete:
consumes:
- application/json
description: |-
Delete a kubernetes namespace within the given environment.
Delete one or more kubernetes namespaces within the given environment.
**Access policy**: Authenticated user.
operationId: DeleteKubernetesNamespace
parameters:
@@ -14336,6 +14402,14 @@ paths:
name: id
required: true
type: integer
- description: List of namespace names to delete
in: body
name: body
required: true
schema:
items:
type: string
type: array
responses:
"200":
description: Success
@@ -14351,7 +14425,7 @@ paths:
security:
- ApiKeyAuth: []
jwt: []
summary: Delete a kubernetes namespace
summary: Delete kubernetes namespaces
tags:
- kubernetes
get:
@@ -14369,13 +14443,11 @@ paths:
of the Namespace information. Default is false
in: query
name: withResourceQuota
required: true
type: boolean
- description: When set to true, include the unhealthy events information as
part of the Namespace information. Default is false
in: query
name: withUnhealthyEvents
required: true
type: boolean
produces:
- application/json
@@ -14433,7 +14505,7 @@ paths:
"200":
description: Success
schema:
$ref: '#/definitions/portainer.K8sNamespaceInfo'
$ref: '#/definitions/kubernetes.KubernetesCreateNamespaceResponse'
"400":
description: Invalid request payload, such as missing required fields or
fields not meeting validation criteria.
@@ -14529,7 +14601,6 @@ paths:
of the Namespace information. Default is false
in: query
name: withResourceQuota
required: true
type: boolean
produces:
- application/json
@@ -17952,7 +18023,7 @@ paths:
"200":
description: OK
schema:
$ref: '#/definitions/portainer.Stack'
$ref: '#/definitions/stacks.createKubernetesStackResponse'
"400":
description: Invalid request
"409":
@@ -17990,7 +18061,7 @@ paths:
"200":
description: OK
schema:
$ref: '#/definitions/portainer.Stack'
$ref: '#/definitions/stacks.createKubernetesStackResponse'
"400":
description: Invalid request
"500":
@@ -18026,7 +18097,7 @@ paths:
"200":
description: OK
schema:
$ref: '#/definitions/portainer.Stack'
$ref: '#/definitions/stacks.createKubernetesStackResponse'
"400":
description: Invalid request
"500":
+14 -8
View File
@@ -10,6 +10,7 @@ import (
"github.com/portainer/portainer/pkg/libhttp/request"
"github.com/portainer/portainer/pkg/libhttp/response"
"github.com/rs/zerolog/log"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
)
@@ -21,8 +22,8 @@ import (
// @security ApiKeyAuth || jwt
// @produce json
// @param id path int true "Environment identifier"
// @param withResourceQuota query boolean true "When set to true, include the resource quota information as part of the Namespace information. Default is false"
// @param withUnhealthyEvents query boolean true "When set to true, include the unhealthy events information as part of the Namespace information. Default is false"
// @param withResourceQuota query boolean false "When set to true, include the resource quota information as part of the Namespace information. Default is false"
// @param withUnhealthyEvents query boolean false "When set to true, include the unhealthy events information as part of the Namespace information. Default is false"
// @success 200 {array} portainer.K8sNamespaceInfo "Success"
// @failure 400 "Invalid request payload, such as missing required fields or fields not meeting validation criteria."
// @failure 401 "Unauthorized access - the user is not authenticated or does not have the necessary permissions. Ensure that you have provided a valid API key or JWT token, and that you have the required permissions."
@@ -110,7 +111,7 @@ func (handler *Handler) getKubernetesNamespacesCount(w http.ResponseWriter, r *h
// @produce json
// @param id path int true "Environment identifier"
// @param namespace path string true "The namespace name to get details for"
// @param withResourceQuota query boolean true "When set to true, include the resource quota information as part of the Namespace information. Default is false"
// @param withResourceQuota query boolean false "When set to true, include the resource quota information as part of the Namespace information. Default is false"
// @success 200 {object} portainer.K8sNamespaceInfo "Success"
// @failure 400 "Invalid request payload, such as missing required fields or fields not meeting validation criteria."
// @failure 401 "Unauthorized access - the user is not authenticated or does not have the necessary permissions. Ensure that you have provided a valid API key or JWT token, and that you have the required permissions."
@@ -170,7 +171,7 @@ func (handler *Handler) getKubernetesNamespace(w http.ResponseWriter, r *http.Re
// @produce json
// @param id path int true "Environment identifier"
// @param body body models.K8sNamespaceDetails true "Namespace configuration details"
// @success 200 {object} portainer.K8sNamespaceInfo "Success"
// @success 200 {object} KubernetesCreateNamespaceResponse "Success"
// @failure 400 "Invalid request payload, such as missing required fields or fields not meeting validation criteria."
// @failure 401 "Unauthorized access - the user is not authenticated or does not have the necessary permissions. Ensure that you have provided a valid API key or JWT token, and that you have the required permissions."
// @failure 403 "Permission denied - the user is authenticated but does not have the necessary permissions to access the requested resource or perform the specified operation. Check your user roles and permissions."
@@ -207,12 +208,14 @@ func (handler *Handler) createKubernetesNamespace(w http.ResponseWriter, r *http
}
// @id DeleteKubernetesNamespace
// @summary Delete a kubernetes namespace
// @description Delete a kubernetes namespace within the given environment.
// @summary Delete kubernetes namespaces
// @description Delete one or more kubernetes namespaces within the given environment.
// @description **Access policy**: Authenticated user.
// @tags kubernetes
// @security ApiKeyAuth || jwt
// @accept json
// @param id path int true "Environment identifier"
// @param body body deleteKubernetesNamespacePayload true "List of namespace names to delete"
// @success 200 {string} string "Success"
// @failure 400 "Invalid request payload, such as missing required fields or fields not meeting validation criteria."
// @failure 403 "Unauthorized access or operation not allowed."
@@ -221,8 +224,8 @@ func (handler *Handler) createKubernetesNamespace(w http.ResponseWriter, r *http
func (handler *Handler) deleteKubernetesNamespace(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
namespaceNames, err := request.GetPayload[deleteKubernetesNamespacePayload](r)
if err != nil {
log.Error().Err(err).Str("context", "DeleteKubernetesNamespace").Msg("Invalid namespace identifier route variable")
return httperror.BadRequest("an error occurred during the DeleteKubernetesNamespace operation, invalid namespace identifier route variable. Error: ", err)
log.Error().Err(err).Str("context", "DeleteKubernetesNamespace").Msg("Invalid request payload")
return httperror.BadRequest("an error occurred during the DeleteKubernetesNamespace operation, invalid request payload. Error: ", err)
}
cli, httpErr := handler.getProxyKubeClient(r)
@@ -256,6 +259,9 @@ func (payload deleteKubernetesNamespacePayload) Validate(r *http.Request) error
return nil
}
// KubernetesCreateNamespaceResponse is the documented response model for namespace create endpoints.
type KubernetesCreateNamespaceResponse corev1.Namespace
// @id UpdateKubernetesNamespace
// @summary Update a namespace
// @description Update a namespace within the given environment.
@@ -0,0 +1,117 @@
package kubernetes
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/datastore"
"github.com/portainer/portainer/api/http/security"
"github.com/portainer/portainer/api/internal/authorization"
"github.com/portainer/portainer/api/internal/testhelpers"
"github.com/portainer/portainer/api/jwt"
"github.com/portainer/portainer/api/kubernetes"
kubeclient "github.com/portainer/portainer/api/kubernetes/cli"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func newNamespaceTestHandler(t *testing.T) (*Handler, *portainer.User, string) {
t.Helper()
srv := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{}`))
}))
t.Cleanup(srv.Close)
_, store := datastore.MustNewTestStore(t, true, true)
err := store.Endpoint().Create(&portainer.Endpoint{
ID: 1,
Type: portainer.KubernetesLocalEnvironment,
})
require.NoError(t, err)
u := &portainer.User{Username: "admin", Role: portainer.AdministratorRole}
err = store.User().Create(u)
require.NoError(t, err)
jwtService, err := jwt.NewService("1h", store)
require.NoError(t, err)
tk, _, err := jwtService.GenerateToken(&portainer.TokenData{ID: u.ID, Username: u.Username, Role: u.Role})
require.NoError(t, err)
kubeClusterAccessService := kubernetes.NewKubeClusterAccessService("", "", "")
srvURL, err := url.Parse(srv.URL)
require.NoError(t, err)
cli := testhelpers.NewKubernetesClient()
factory, err := kubeclient.NewClientFactory(nil, nil, store, "", ":"+srvURL.Port(), "")
require.NoError(t, err)
authorizationService := authorization.NewService(store)
handler := NewHandler(testhelpers.NewTestRequestBouncer(), authorizationService, store, jwtService, kubeClusterAccessService, factory, cli)
return handler, u, tk
}
func newNamespaceRequest(t *testing.T, method, path string, body any, u *portainer.User, tk string) *http.Request {
t.Helper()
var bodyReader *bytes.Reader
if body != nil {
b, err := json.Marshal(body)
require.NoError(t, err)
bodyReader = bytes.NewReader(b)
} else {
bodyReader = bytes.NewReader(nil)
}
req := httptest.NewRequest(method, path, bodyReader)
req.Header.Set("Content-Type", "application/json")
ctx := security.StoreTokenData(req, &portainer.TokenData{ID: u.ID, Username: u.Username, Role: u.Role})
req = req.WithContext(ctx)
ctx = security.StoreRestrictedRequestContext(req, &security.RestrictedRequestContext{IsAdmin: true, UserID: u.ID})
req = req.WithContext(ctx)
testhelpers.AddTestSecurityCookie(req, tk)
return req
}
func TestDeleteKubernetesNamespace_InvalidPayload(t *testing.T) {
t.Parallel()
handler, u, tk := newNamespaceTestHandler(t)
req := httptest.NewRequest(http.MethodDelete, "/kubernetes/1/namespaces", strings.NewReader("not-valid-json"))
req.Header.Set("Content-Type", "application/json")
ctx := security.StoreTokenData(req, &portainer.TokenData{ID: u.ID, Username: u.Username, Role: u.Role})
req = req.WithContext(ctx)
ctx = security.StoreRestrictedRequestContext(req, &security.RestrictedRequestContext{IsAdmin: true, UserID: u.ID})
req = req.WithContext(ctx)
testhelpers.AddTestSecurityCookie(req, tk)
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
assert.Equal(t, http.StatusBadRequest, rr.Code)
}
func TestDeleteKubernetesNamespace_ReachesKubernetesLayer(t *testing.T) {
t.Parallel()
handler, u, tk := newNamespaceTestHandler(t)
req := newNamespaceRequest(t, http.MethodDelete, "/kubernetes/1/namespaces", []string{"default"}, u, tk)
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
assert.NotEqual(t, http.StatusBadRequest, rr.Code, "should not be rejected at the handler layer")
assert.NotEqual(t, http.StatusNotFound, rr.Code, "route must be registered")
}
@@ -149,7 +149,7 @@ type createKubernetesStackResponse struct {
// @produce json
// @param body body kubernetesStringDeploymentPayload true "stack config"
// @param endpointId query int true "Identifier of the environment that will be used to deploy the stack"
// @success 200 {object} portainer.Stack
// @success 200 {object} createKubernetesStackResponse
// @failure 400 "Invalid request"
// @failure 500 "Server error"
// @router /stacks/create/kubernetes/string [post]
@@ -207,7 +207,7 @@ func (handler *Handler) createKubernetesStackFromFileContent(w http.ResponseWrit
// @produce json
// @param body body kubernetesGitDeploymentPayload true "stack config"
// @param endpointId query int true "Identifier of the environment that will be used to deploy the stack"
// @success 200 {object} portainer.Stack
// @success 200 {object} createKubernetesStackResponse
// @failure 400 "Invalid request"
// @failure 409 "Stack name or webhook ID already exists"
// @failure 500 "Server error"
@@ -289,7 +289,7 @@ func (handler *Handler) createKubernetesStackFromGitRepository(w http.ResponseWr
// @produce json
// @param body body kubernetesManifestURLDeploymentPayload true "stack config"
// @param endpointId query int true "Identifier of the environment that will be used to deploy the stack"
// @success 200 {object} portainer.Stack
// @success 200 {object} createKubernetesStackResponse
// @failure 400 "Invalid request"
// @failure 500 "Server error"
// @router /stacks/create/kubernetes/url [post]
@@ -834,6 +834,7 @@ import {
zDeleteKubernetesIngressesBody,
zDeleteKubernetesIngressesPath,
zDeleteKubernetesIngressesResponse,
zDeleteKubernetesNamespaceBody,
zDeleteKubernetesNamespacePath,
zDeleteKubernetesNamespaceResponse,
zDeleteKubernetesPersistentVolumeClaimsBody,
@@ -5534,9 +5535,9 @@ export const getKubernetesMetricsForPod = <ThrowOnError extends boolean = true>(
});
/**
* Delete a kubernetes namespace
* Delete kubernetes namespaces
*
* Delete a kubernetes namespace within the given environment.
* Delete one or more kubernetes namespaces within the given environment.
* **Access policy**: Authenticated user.
*/
export const deleteKubernetesNamespace = <ThrowOnError extends boolean = true>(
@@ -5554,7 +5555,7 @@ export const deleteKubernetesNamespace = <ThrowOnError extends boolean = true>(
requestValidator: async (data) =>
await z
.object({
body: z.never().optional(),
body: zDeleteKubernetesNamespaceBody,
path: zDeleteKubernetesNamespacePath,
query: z.never().optional(),
})
@@ -5567,6 +5568,10 @@ export const deleteKubernetesNamespace = <ThrowOnError extends boolean = true>(
],
url: '/kubernetes/{id}/namespaces',
...options,
headers: {
'Content-Type': 'application/json',
...options.headers,
},
});
/**
@@ -5592,7 +5597,7 @@ export const getKubernetesNamespaces = <ThrowOnError extends boolean = true>(
.object({
body: z.never().optional(),
path: zGetKubernetesNamespacesPath,
query: zGetKubernetesNamespacesQuery,
query: zGetKubernetesNamespacesQuery.optional(),
})
.parseAsync(data),
responseType: 'json',
@@ -5713,7 +5718,7 @@ export const getKubernetesNamespace = <ThrowOnError extends boolean = true>(
.object({
body: z.never().optional(),
path: zGetKubernetesNamespacePath,
query: zGetKubernetesNamespaceQuery,
query: zGetKubernetesNamespaceQuery.optional(),
})
.parseAsync(data),
responseType: 'json',
@@ -1479,6 +1479,44 @@ export type KubernetesK8sVolumeInfo = {
storageClass?: KubernetesK8sStorageClass;
};
export type KubernetesKubernetesCreateNamespaceResponse = {
/**
* APIVersion defines the versioned schema of this representation of an object.
* Servers should convert recognized schemas to the latest internal value, and
* may reject unrecognized values.
* More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
* +optional
*/
apiVersion?: string;
/**
* Kind is a string value representing the REST resource this object represents.
* Servers may infer this from the endpoint the client submits requests to.
* Cannot be updated.
* In CamelCase.
* More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
* +optional
*/
kind?: string;
/**
* Standard object's metadata.
* More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
* +optional
*/
metadata?: V1ObjectMeta;
/**
* Spec defines the behavior of the Namespace.
* More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
* +optional
*/
spec?: V1NamespaceSpec;
/**
* Status describes the current status of a Namespace.
* More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
* +optional
*/
status?: V1NamespaceStatus;
};
export type KubernetesKubernetesNodeResponse = {
/**
* APIVersion defines the versioned schema of this representation of an object.
@@ -4525,6 +4563,10 @@ export type StacksComposeStackFromGitRepositoryPayload = {
TLSSkipVerify?: boolean;
};
export type StacksCreateKubernetesStackResponse = {
Output?: string;
};
export type StacksKubernetesGitDeploymentPayload = {
AdditionalFiles?: Array<string>;
AutoUpdate?: PortainerAutoUpdateSettings;
@@ -5845,6 +5887,16 @@ export type V1FileKeySelector = {
volumeName?: string;
};
export const V1FinalizerName = {
/**
* FinalizerKubernetes
*/
FINALIZER_KUBERNETES: 'kubernetes',
} as const;
export type V1FinalizerName =
(typeof V1FinalizerName)[keyof typeof V1FinalizerName];
export type V1GrpcAction = {
/**
* Port number of the gRPC service. Number must be in the range 1 to 65535.
@@ -6135,6 +6187,16 @@ export const V1NamespacePhase = {
export type V1NamespacePhase =
(typeof V1NamespacePhase)[keyof typeof V1NamespacePhase];
export type V1NamespaceSpec = {
/**
* Finalizers is an opaque list of values that must be empty to permanently remove object from storage.
* More info: https://kubernetes.io/docs/tasks/administer-cluster/namespaces/
* +optional
* +listType=atomic
*/
finalizers?: Array<V1FinalizerName>;
};
export type V1NamespaceStatus = {
/**
* Represents the latest available observations of a namespace's current state.
@@ -13123,7 +13185,10 @@ export type GetKubernetesMetricsForPodResponse =
GetKubernetesMetricsForPodResponses[keyof GetKubernetesMetricsForPodResponses];
export type DeleteKubernetesNamespaceData = {
body?: never;
/**
* List of namespace names to delete
*/
body: Array<string>;
path: {
/**
* Environment identifier
@@ -13167,15 +13232,15 @@ export type GetKubernetesNamespacesData = {
*/
id: number;
};
query: {
query?: {
/**
* When set to true, include the resource quota information as part of the Namespace information. Default is false
*/
withResourceQuota: boolean;
withResourceQuota?: boolean;
/**
* When set to true, include the unhealthy events information as part of the Namespace information. Default is false
*/
withUnhealthyEvents: boolean;
withUnhealthyEvents?: boolean;
};
url: '/kubernetes/{id}/namespaces';
};
@@ -13255,7 +13320,7 @@ export type CreateKubernetesNamespaceResponses = {
/**
* Success
*/
200: PortainerK8sNamespaceInfo;
200: KubernetesKubernetesCreateNamespaceResponse;
};
export type CreateKubernetesNamespaceResponse =
@@ -13325,11 +13390,11 @@ export type GetKubernetesNamespaceData = {
*/
namespace: string;
};
query: {
query?: {
/**
* When set to true, include the resource quota information as part of the Namespace information. Default is false
*/
withResourceQuota: boolean;
withResourceQuota?: boolean;
};
url: '/kubernetes/{id}/namespaces/{namespace}';
};
@@ -17021,7 +17086,7 @@ export type StackCreateKubernetesGitResponses = {
/**
* OK
*/
200: PortainerStack;
200: StacksCreateKubernetesStackResponse;
};
export type StackCreateKubernetesGitResponse =
@@ -17057,7 +17122,7 @@ export type StackCreateKubernetesFileResponses = {
/**
* OK
*/
200: PortainerStack;
200: StacksCreateKubernetesStackResponse;
};
export type StackCreateKubernetesFileResponse =
@@ -17093,7 +17158,7 @@ export type StackCreateKubernetesUrlResponses = {
/**
* OK
*/
200: PortainerStack;
200: StacksCreateKubernetesStackResponse;
};
export type StackCreateKubernetesUrlResponse =
@@ -2120,6 +2120,10 @@ export const zStacksComposeStackFromGitRepositoryPayload = z.object({
TLSSkipVerify: z.boolean().optional(),
});
export const zStacksCreateKubernetesStackResponse = z.object({
Output: z.string().optional(),
});
export const zStacksKubernetesGitDeploymentPayload = z.object({
AdditionalFiles: z.array(z.string()).optional(),
AutoUpdate: zPortainerAutoUpdateSettings.optional(),
@@ -2511,6 +2515,8 @@ export const zV1FileKeySelector = z.object({
volumeName: z.string().optional(),
});
export const zV1FinalizerName = z.enum(['kubernetes']);
export const zV1GrpcAction = z.object({
port: z.int().optional(),
service: z.string().optional(),
@@ -2559,6 +2565,10 @@ export const zV1NamespaceCondition = z.object({
export const zV1NamespacePhase = z.enum(['Active', 'Terminating']);
export const zV1NamespaceSpec = z.object({
finalizers: z.array(zV1FinalizerName).optional(),
});
export const zV1NamespaceStatus = z.object({
conditions: z.array(zV1NamespaceCondition).optional(),
phase: zV1NamespacePhase.optional(),
@@ -2675,6 +2685,14 @@ export const zV1ObjectMeta = z.object({
uid: z.string().optional(),
});
export const zKubernetesKubernetesCreateNamespaceResponse = z.object({
apiVersion: z.string().optional(),
kind: z.string().optional(),
metadata: zV1ObjectMeta.optional(),
spec: zV1NamespaceSpec.optional(),
status: zV1NamespaceStatus.optional(),
});
export const zV1PersistentVolumeAccessMode = z.enum([
'ReadWriteOnce',
'ReadOnlyMany',
@@ -4796,6 +4814,11 @@ export const zGetKubernetesMetricsForPodPath = z.object({
*/
export const zGetKubernetesMetricsForPodResponse = zV1Beta1PodMetrics;
/**
* List of namespace names to delete
*/
export const zDeleteKubernetesNamespaceBody = z.array(z.string());
export const zDeleteKubernetesNamespacePath = z.object({
id: z.int(),
});
@@ -4810,8 +4833,8 @@ export const zGetKubernetesNamespacesPath = z.object({
});
export const zGetKubernetesNamespacesQuery = z.object({
withResourceQuota: z.boolean(),
withUnhealthyEvents: z.boolean(),
withResourceQuota: z.boolean().optional(),
withUnhealthyEvents: z.boolean().optional(),
});
/**
@@ -4833,7 +4856,8 @@ export const zCreateKubernetesNamespacePath = z.object({
/**
* Success
*/
export const zCreateKubernetesNamespaceResponse = zPortainerK8sNamespaceInfo;
export const zCreateKubernetesNamespaceResponse =
zKubernetesKubernetesCreateNamespaceResponse;
/**
* Namespace details
@@ -4858,7 +4882,7 @@ export const zGetKubernetesNamespacePath = z.object({
});
export const zGetKubernetesNamespaceQuery = z.object({
withResourceQuota: z.boolean(),
withResourceQuota: z.boolean().optional(),
});
/**
@@ -5855,7 +5879,8 @@ export const zStackCreateKubernetesGitQuery = z.object({
/**
* OK
*/
export const zStackCreateKubernetesGitResponse = zPortainerStack;
export const zStackCreateKubernetesGitResponse =
zStacksCreateKubernetesStackResponse;
/**
* stack config
@@ -5870,7 +5895,8 @@ export const zStackCreateKubernetesFileQuery = z.object({
/**
* OK
*/
export const zStackCreateKubernetesFileResponse = zPortainerStack;
export const zStackCreateKubernetesFileResponse =
zStacksCreateKubernetesStackResponse;
/**
* stack config
@@ -5885,7 +5911,8 @@ export const zStackCreateKubernetesUrlQuery = z.object({
/**
* OK
*/
export const zStackCreateKubernetesUrlResponse = zPortainerStack;
export const zStackCreateKubernetesUrlResponse =
zStacksCreateKubernetesStackResponse;
export const zStackCreateDockerStandaloneFileBody = z.object({
Name: z.string(),