@@ -0,0 +1,31 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/.well-known/openid-configuration/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"WellKnown"
|
||||
],
|
||||
"description": "get service account issuer OpenID configuration, also known as the 'OIDC discovery doc'",
|
||||
"operationId": "getServiceAccountIssuerOpenIDConfiguration",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {}
|
||||
}
|
30155
api/openapi-spec/v3/api__v1_openapi.json
Normal file
30155
api/openapi-spec/v3/api__v1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
105
api/openapi-spec/v3/api_openapi.json
Normal file
105
api/openapi-spec/v3/api_openapi.json
Normal file
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/api/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"core"
|
||||
],
|
||||
"description": "get available API versions",
|
||||
"operationId": "getCoreAPIVersions",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIVersions"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIVersions"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIVersions"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIVersions": {
|
||||
"description": "APIVersions lists the versions that are available, to allow clients to discover the API at /api, which is the root path of the legacy v1 API.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"versions",
|
||||
"serverAddressByClientCIDRs"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the api versions that are available.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIVersions",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/admissionregistration.k8s.io/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"admissionregistration"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getAdmissionregistrationAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2939
api/openapi-spec/v3/apis__apiextensions.k8s.io__v1_openapi.json
Normal file
2939
api/openapi-spec/v3/apis__apiextensions.k8s.io__v1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
135
api/openapi-spec/v3/apis__apiextensions.k8s.io_openapi.json
Normal file
135
api/openapi-spec/v3/apis__apiextensions.k8s.io_openapi.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/apiextensions.k8s.io/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"apiextensions"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getApiextensionsAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13069
api/openapi-spec/v3/apis__apps__v1_openapi.json
Normal file
13069
api/openapi-spec/v3/apis__apps__v1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
135
api/openapi-spec/v3/apis__apps_openapi.json
Normal file
135
api/openapi-spec/v3/apis__apps_openapi.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/apps/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"apps"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getAppsAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
557
api/openapi-spec/v3/apis__authentication.k8s.io__v1_openapi.json
Normal file
557
api/openapi-spec/v3/apis__authentication.k8s.io__v1_openapi.json
Normal file
@@ -0,0 +1,557 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/authentication.k8s.io/v1/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"authentication_v1"
|
||||
],
|
||||
"description": "get available resources",
|
||||
"operationId": "getAuthenticationV1APIResources",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIResourceList"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIResourceList"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIResourceList"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/apis/authentication.k8s.io/v1/tokenreviews": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"authentication_v1"
|
||||
],
|
||||
"description": "create a TokenReview",
|
||||
"operationId": "createAuthenticationV1TokenReview",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.api.authentication.v1.TokenReview"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.api.authentication.v1.TokenReview"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.api.authentication.v1.TokenReview"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.api.authentication.v1.TokenReview"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.api.authentication.v1.TokenReview"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.api.authentication.v1.TokenReview"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.api.authentication.v1.TokenReview"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"202": {
|
||||
"description": "Accepted",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.api.authentication.v1.TokenReview"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.api.authentication.v1.TokenReview"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.api.authentication.v1.TokenReview"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "dryRun",
|
||||
"in": "query",
|
||||
"description": "When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"uniqueItems": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "fieldManager",
|
||||
"in": "query",
|
||||
"description": "fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"uniqueItems": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "pretty",
|
||||
"in": "query",
|
||||
"description": "If 'true', then the output is pretty printed.",
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"uniqueItems": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.api.authentication.v1.TokenReview": {
|
||||
"description": "TokenReview attempts to authenticate a token to a known user. Note: TokenReview requests may be cached by the webhook token authenticator plugin in the kube-apiserver.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"spec"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"metadata": {
|
||||
"description": "Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"
|
||||
},
|
||||
"spec": {
|
||||
"description": "Spec holds information about the request being evaluated",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.api.authentication.v1.TokenReviewSpec"
|
||||
},
|
||||
"status": {
|
||||
"description": "Status is filled in by the server and indicates whether the request can be authenticated.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.api.authentication.v1.TokenReviewStatus"
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "authentication.k8s.io",
|
||||
"kind": "TokenReview",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.api.authentication.v1.TokenReviewSpec": {
|
||||
"description": "TokenReviewSpec is a description of the token authentication request.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"audiences": {
|
||||
"description": "Audiences is a list of the identifiers that the resource server presented with the token identifies as. Audience-aware token authenticators will verify that the token was intended for at least one of the audiences in this list. If no audiences are provided, the audience will default to the audience of the Kubernetes apiserver.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
},
|
||||
"token": {
|
||||
"description": "Token is the opaque bearer token.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.api.authentication.v1.TokenReviewStatus": {
|
||||
"description": "TokenReviewStatus is the result of the token authentication request.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"audiences": {
|
||||
"description": "Audiences are audience identifiers chosen by the authenticator that are compatible with both the TokenReview and token. An identifier is any identifier in the intersection of the TokenReviewSpec audiences and the token's audiences. A client of the TokenReview API that sets the spec.audiences field should validate that a compatible audience identifier is returned in the status.audiences field to ensure that the TokenReview server is audience aware. If a TokenReview returns an empty status.audience field where status.authenticated is \"true\", the token is valid against the audience of the Kubernetes API server.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
},
|
||||
"authenticated": {
|
||||
"description": "Authenticated indicates that the token was associated with a known user.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"error": {
|
||||
"description": "Error indicates that the token couldn't be checked",
|
||||
"type": "string"
|
||||
},
|
||||
"user": {
|
||||
"description": "User is the UserInfo associated with the provided token.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.api.authentication.v1.UserInfo"
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.api.authentication.v1.UserInfo": {
|
||||
"description": "UserInfo holds the information about the user needed to implement the user.Info interface.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"extra": {
|
||||
"description": "Any additional information provided by the authenticator.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"groups": {
|
||||
"description": "The names of groups this user is a part of.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
},
|
||||
"uid": {
|
||||
"description": "A unique value that identifies this user across time. If this user is deleted and another user by the same name is added, they will have different UIDs.",
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"description": "The name that uniquely identifies this user among all active users.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIResource": {
|
||||
"description": "APIResource specifies the name of a resource and whether it is namespaced.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"singularName",
|
||||
"namespaced",
|
||||
"kind",
|
||||
"verbs"
|
||||
],
|
||||
"properties": {
|
||||
"categories": {
|
||||
"description": "categories is a list of the grouped resources this resource belongs to (e.g. 'all')",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"description": "group is the preferred group of the resource. Empty implies the group of the containing resource list. For subresources, this may have a different value, for example: Scale\".",
|
||||
"type": "string"
|
||||
},
|
||||
"kind": {
|
||||
"description": "kind is the kind for the resource (e.g. 'Foo' is the kind for a resource 'foo')",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the plural name of the resource.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"namespaced": {
|
||||
"description": "namespaced indicates if a resource is namespaced or not.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"shortNames": {
|
||||
"description": "shortNames is a list of suggested short names of the resource.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
},
|
||||
"singularName": {
|
||||
"description": "singularName is the singular name of the resource. This allows clients to handle plural and singular opaquely. The singularName is more correct for reporting status on a single item and both singular and plural are allowed from the kubectl CLI interface.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"storageVersionHash": {
|
||||
"description": "The hash value of the storage version, the version this resource is converted to when written to the data store. Value must be treated as opaque by clients. Only equality comparison on the value is valid. This is an alpha feature and may change or be removed in the future. The field is populated by the apiserver only if the StorageVersionHash feature gate is enabled. This field will remain optional even if it graduates.",
|
||||
"type": "string"
|
||||
},
|
||||
"verbs": {
|
||||
"description": "verbs is a list of supported kube verbs (this includes get, list, watch, create, update, patch, delete, deletecollection, and proxy)",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
},
|
||||
"version": {
|
||||
"description": "version is the preferred version of the resource. Empty implies the version of the containing resource list For subresources, this may have a different value, for example: v1 (while inside a v1beta1 version of the core resource's group)\".",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIResourceList": {
|
||||
"description": "APIResourceList is a list of APIResource, it is used to expose the name of the resources supported in a specific group and version, and if the resource is namespaced.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"resources"
|
||||
],
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"groupVersion": {
|
||||
"description": "groupVersion is the group and version this APIResourceList is for.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"resources": {
|
||||
"description": "resources contains the name of the resources and if they are namespaced.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIResource"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIResourceList",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1": {
|
||||
"description": "FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format.\n\nEach key is either a '.' representing the field itself, and will always map to an empty set, or a string representing a sub-field or item. The string will follow one of these four formats: 'f:<name>', where <name> is the name of a field in a struct, or key in a map 'v:<value>', where <value> is the exact json formatted value of a list item 'i:<index>', where <index> is position of a item in a list 'k:<keys>', where <keys> is a map of a list item's key fields to their unique values If a key maps to an empty Fields value, the field that key represents is part of the set.\n\nThe exact format is defined in sigs.k8s.io/structured-merge-diff",
|
||||
"type": "object"
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry": {
|
||||
"description": "ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource that the fieldset applies to.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"apiVersion": {
|
||||
"description": "APIVersion defines the version of this resource that this field set applies to. The format is \"group/version\" just like the top-level APIVersion field. It is necessary to track the version of a field set because it cannot be automatically converted.",
|
||||
"type": "string"
|
||||
},
|
||||
"fieldsType": {
|
||||
"description": "FieldsType is the discriminator for the different fields format and version. There is currently only one possible value: \"FieldsV1\"",
|
||||
"type": "string"
|
||||
},
|
||||
"fieldsV1": {
|
||||
"description": "FieldsV1 holds the first JSON version format as described in the \"FieldsV1\" type.",
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1"
|
||||
},
|
||||
"manager": {
|
||||
"description": "Manager is an identifier of the workflow managing these fields.",
|
||||
"type": "string"
|
||||
},
|
||||
"operation": {
|
||||
"description": "Operation is the type of operation which lead to this ManagedFieldsEntry being created. The only valid values for this field are 'Apply' and 'Update'.",
|
||||
"type": "string"
|
||||
},
|
||||
"subresource": {
|
||||
"description": "Subresource is the name of the subresource used to update that object, or empty string if the object was updated through the main resource. The value of this field is used to distinguish between managers, even if they share the same name. For example, a status update will be distinct from a regular update using the same manager name. Note that the APIVersion field is not related to the Subresource field and it always corresponds to the version of the main resource.",
|
||||
"type": "string"
|
||||
},
|
||||
"time": {
|
||||
"description": "Time is timestamp of when these fields were set. It should always be empty if Operation is 'Apply'",
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time"
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": {
|
||||
"description": "ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"annotations": {
|
||||
"description": "Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
},
|
||||
"clusterName": {
|
||||
"description": "The name of the cluster which the object belongs to. This is used to distinguish resources with same name and namespace in different clusters. This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.",
|
||||
"type": "string"
|
||||
},
|
||||
"creationTimestamp": {
|
||||
"description": "CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time"
|
||||
},
|
||||
"deletionGracePeriodSeconds": {
|
||||
"description": "Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.",
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"deletionTimestamp": {
|
||||
"description": "DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.\n\nPopulated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata",
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.Time"
|
||||
},
|
||||
"finalizers": {
|
||||
"description": "Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"x-kubernetes-patch-strategy": "merge"
|
||||
},
|
||||
"generateName": {
|
||||
"description": "GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.\n\nIf this field is specified and the generated name exists, the server will NOT return a 409 - instead, it will either return 201 Created or 500 with Reason ServerTimeout indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header).\n\nApplied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency",
|
||||
"type": "string"
|
||||
},
|
||||
"generation": {
|
||||
"description": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.",
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"labels": {
|
||||
"description": "Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
},
|
||||
"managedFields": {
|
||||
"description": "ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like \"ci-cd\". The set of fields is always in the version that the workflow used when modifying the object.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"description": "Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
|
||||
"type": "string"
|
||||
},
|
||||
"namespace": {
|
||||
"description": "Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the \"default\" namespace, but \"default\" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces",
|
||||
"type": "string"
|
||||
},
|
||||
"ownerReferences": {
|
||||
"description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference"
|
||||
},
|
||||
"x-kubernetes-patch-merge-key": "uid",
|
||||
"x-kubernetes-patch-strategy": "merge"
|
||||
},
|
||||
"resourceVersion": {
|
||||
"description": "An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.\n\nPopulated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency",
|
||||
"type": "string"
|
||||
},
|
||||
"selfLink": {
|
||||
"description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.",
|
||||
"type": "string"
|
||||
},
|
||||
"uid": {
|
||||
"description": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference": {
|
||||
"description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"apiVersion",
|
||||
"kind",
|
||||
"name",
|
||||
"uid"
|
||||
],
|
||||
"properties": {
|
||||
"apiVersion": {
|
||||
"description": "API version of the referent.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"blockOwnerDeletion": {
|
||||
"description": "If true, AND if the owner has the \"foregroundDeletion\" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed. Defaults to false. To set this field, a user needs \"delete\" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"controller": {
|
||||
"description": "If true, this reference points to the managing controller.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"kind": {
|
||||
"description": "Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"name": {
|
||||
"description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"uid": {
|
||||
"description": "UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
},
|
||||
"x-kubernetes-map-type": "atomic"
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.Time": {
|
||||
"description": "Time is a wrapper around time.Time which supports correct marshaling to YAML and JSON. Wrappers are provided for many of the factory methods that the time package offers.",
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
135
api/openapi-spec/v3/apis__authentication.k8s.io_openapi.json
Normal file
135
api/openapi-spec/v3/apis__authentication.k8s.io_openapi.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/authentication.k8s.io/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"authentication"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getAuthenticationAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1174
api/openapi-spec/v3/apis__authorization.k8s.io__v1_openapi.json
Normal file
1174
api/openapi-spec/v3/apis__authorization.k8s.io__v1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
135
api/openapi-spec/v3/apis__authorization.k8s.io_openapi.json
Normal file
135
api/openapi-spec/v3/apis__authorization.k8s.io_openapi.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/authorization.k8s.io/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"authorization"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getAuthorizationAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2717
api/openapi-spec/v3/apis__autoscaling__v1_openapi.json
Normal file
2717
api/openapi-spec/v3/apis__autoscaling__v1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
3252
api/openapi-spec/v3/apis__autoscaling__v2_openapi.json
Normal file
3252
api/openapi-spec/v3/apis__autoscaling__v2_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
3166
api/openapi-spec/v3/apis__autoscaling__v2beta1_openapi.json
Normal file
3166
api/openapi-spec/v3/apis__autoscaling__v2beta1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
3243
api/openapi-spec/v3/apis__autoscaling__v2beta2_openapi.json
Normal file
3243
api/openapi-spec/v3/apis__autoscaling__v2beta2_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
135
api/openapi-spec/v3/apis__autoscaling_openapi.json
Normal file
135
api/openapi-spec/v3/apis__autoscaling_openapi.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/autoscaling/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"autoscaling"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getAutoscalingAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
7377
api/openapi-spec/v3/apis__batch__v1_openapi.json
Normal file
7377
api/openapi-spec/v3/apis__batch__v1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
5685
api/openapi-spec/v3/apis__batch__v1beta1_openapi.json
Normal file
5685
api/openapi-spec/v3/apis__batch__v1beta1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
135
api/openapi-spec/v3/apis__batch_openapi.json
Normal file
135
api/openapi-spec/v3/apis__batch_openapi.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/batch/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"batch"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getBatchAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2657
api/openapi-spec/v3/apis__certificates.k8s.io__v1_openapi.json
Normal file
2657
api/openapi-spec/v3/apis__certificates.k8s.io__v1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
135
api/openapi-spec/v3/apis__certificates.k8s.io_openapi.json
Normal file
135
api/openapi-spec/v3/apis__certificates.k8s.io_openapi.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/certificates.k8s.io/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"certificates"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getCertificatesAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2426
api/openapi-spec/v3/apis__coordination.k8s.io__v1_openapi.json
Normal file
2426
api/openapi-spec/v3/apis__coordination.k8s.io__v1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
135
api/openapi-spec/v3/apis__coordination.k8s.io_openapi.json
Normal file
135
api/openapi-spec/v3/apis__coordination.k8s.io_openapi.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/coordination.k8s.io/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"coordination"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getCoordinationAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2577
api/openapi-spec/v3/apis__discovery.k8s.io__v1_openapi.json
Normal file
2577
api/openapi-spec/v3/apis__discovery.k8s.io__v1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
2567
api/openapi-spec/v3/apis__discovery.k8s.io__v1beta1_openapi.json
Normal file
2567
api/openapi-spec/v3/apis__discovery.k8s.io__v1beta1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
135
api/openapi-spec/v3/apis__discovery.k8s.io_openapi.json
Normal file
135
api/openapi-spec/v3/apis__discovery.k8s.io_openapi.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/discovery.k8s.io/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"discovery"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getDiscoveryAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2528
api/openapi-spec/v3/apis__events.k8s.io__v1_openapi.json
Normal file
2528
api/openapi-spec/v3/apis__events.k8s.io__v1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
2528
api/openapi-spec/v3/apis__events.k8s.io__v1beta1_openapi.json
Normal file
2528
api/openapi-spec/v3/apis__events.k8s.io__v1beta1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
135
api/openapi-spec/v3/apis__events.k8s.io_openapi.json
Normal file
135
api/openapi-spec/v3/apis__events.k8s.io_openapi.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/events.k8s.io/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"events"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getEventsAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/flowcontrol.apiserver.k8s.io/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"flowcontrolApiserver"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getFlowcontrolApiserverAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
135
api/openapi-spec/v3/apis__internal.apiserver.k8s.io_openapi.json
Normal file
135
api/openapi-spec/v3/apis__internal.apiserver.k8s.io_openapi.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/internal.apiserver.k8s.io/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"internalApiserver"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getInternalApiserverAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
5489
api/openapi-spec/v3/apis__networking.k8s.io__v1_openapi.json
Normal file
5489
api/openapi-spec/v3/apis__networking.k8s.io__v1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
135
api/openapi-spec/v3/apis__networking.k8s.io_openapi.json
Normal file
135
api/openapi-spec/v3/apis__networking.k8s.io_openapi.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/networking.k8s.io/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"networking"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getNetworkingAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2176
api/openapi-spec/v3/apis__node.k8s.io__v1_openapi.json
Normal file
2176
api/openapi-spec/v3/apis__node.k8s.io__v1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
2190
api/openapi-spec/v3/apis__node.k8s.io__v1alpha1_openapi.json
Normal file
2190
api/openapi-spec/v3/apis__node.k8s.io__v1alpha1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
2176
api/openapi-spec/v3/apis__node.k8s.io__v1beta1_openapi.json
Normal file
2176
api/openapi-spec/v3/apis__node.k8s.io__v1beta1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
135
api/openapi-spec/v3/apis__node.k8s.io_openapi.json
Normal file
135
api/openapi-spec/v3/apis__node.k8s.io_openapi.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/node.k8s.io/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"node"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getNodeAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2808
api/openapi-spec/v3/apis__policy__v1_openapi.json
Normal file
2808
api/openapi-spec/v3/apis__policy__v1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
4220
api/openapi-spec/v3/apis__policy__v1beta1_openapi.json
Normal file
4220
api/openapi-spec/v3/apis__policy__v1beta1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
135
api/openapi-spec/v3/apis__policy_openapi.json
Normal file
135
api/openapi-spec/v3/apis__policy_openapi.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/policy/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"policy"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getPolicyAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
5990
api/openapi-spec/v3/apis__rbac.authorization.k8s.io__v1_openapi.json
Normal file
5990
api/openapi-spec/v3/apis__rbac.authorization.k8s.io__v1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
135
api/openapi-spec/v3/apis__rbac.authorization.k8s.io_openapi.json
Normal file
135
api/openapi-spec/v3/apis__rbac.authorization.k8s.io_openapi.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/rbac.authorization.k8s.io/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"rbacAuthorization"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getRbacAuthorizationAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2103
api/openapi-spec/v3/apis__scheduling.k8s.io__v1_openapi.json
Normal file
2103
api/openapi-spec/v3/apis__scheduling.k8s.io__v1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
135
api/openapi-spec/v3/apis__scheduling.k8s.io_openapi.json
Normal file
135
api/openapi-spec/v3/apis__scheduling.k8s.io_openapi.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/scheduling.k8s.io/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"scheduling"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getSchedulingAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
6672
api/openapi-spec/v3/apis__storage.k8s.io__v1_openapi.json
Normal file
6672
api/openapi-spec/v3/apis__storage.k8s.io__v1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
2469
api/openapi-spec/v3/apis__storage.k8s.io__v1alpha1_openapi.json
Normal file
2469
api/openapi-spec/v3/apis__storage.k8s.io__v1alpha1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
2469
api/openapi-spec/v3/apis__storage.k8s.io__v1beta1_openapi.json
Normal file
2469
api/openapi-spec/v3/apis__storage.k8s.io__v1beta1_openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
135
api/openapi-spec/v3/apis__storage.k8s.io_openapi.json
Normal file
135
api/openapi-spec/v3/apis__storage.k8s.io_openapi.json
Normal file
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/storage.k8s.io/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"storage"
|
||||
],
|
||||
"description": "get information of a group",
|
||||
"operationId": "getStorageAPIGroup",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
167
api/openapi-spec/v3/apis_openapi.json
Normal file
167
api/openapi-spec/v3/apis_openapi.json
Normal file
@@ -0,0 +1,167 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/apis/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"apis"
|
||||
],
|
||||
"description": "get available API versions",
|
||||
"operationId": "getAPIVersions",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroupList"
|
||||
}
|
||||
},
|
||||
"application/vnd.kubernetes.protobuf": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroupList"
|
||||
}
|
||||
},
|
||||
"application/yaml": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroupList"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup": {
|
||||
"description": "APIGroup contains the name, the supported versions, and the preferred version of a group.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name",
|
||||
"versions"
|
||||
],
|
||||
"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",
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "name is the name of the group.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"preferredVersion": {
|
||||
"description": "preferredVersion is the version preferred by the API server, which probably is the storage version.",
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
},
|
||||
"serverAddressByClientCIDRs": {
|
||||
"description": "a map of client CIDR to server address that is serving this group. This is to help clients reach servers in the most network-efficient way possible. Clients can use the appropriate server address as per the CIDR that they match. In case of multiple matches, clients should use the longest matching CIDR. The server returns only those CIDRs that it thinks that the client can match. For example: the master will return an internal IP CIDR only, if the client reaches the server using an internal IP. Server looks at X-Forwarded-For header or X-Real-Ip header or request.RemoteAddr (in that order) to get the client IP.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR"
|
||||
}
|
||||
},
|
||||
"versions": {
|
||||
"description": "versions are the versions supported in this group.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroup",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.APIGroupList": {
|
||||
"description": "APIGroupList is a list of APIGroup, to allow clients to discover the API at /apis.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groups"
|
||||
],
|
||||
"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",
|
||||
"type": "string"
|
||||
},
|
||||
"groups": {
|
||||
"description": "groups is a list of APIGroup.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"default": {},
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.APIGroup"
|
||||
}
|
||||
},
|
||||
"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",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"x-kubernetes-group-version-kind": [
|
||||
{
|
||||
"group": "",
|
||||
"kind": "APIGroupList",
|
||||
"version": "v1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.GroupVersionForDiscovery": {
|
||||
"description": "GroupVersion contains the \"group/version\" and \"version\" string of a version. It is made a struct to keep extensibility.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"groupVersion",
|
||||
"version"
|
||||
],
|
||||
"properties": {
|
||||
"groupVersion": {
|
||||
"description": "groupVersion specifies the API group and version in the form \"group/version\"",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"version": {
|
||||
"description": "version specifies the version in the form of \"version\". This is to save the clients the trouble of splitting the GroupVersion.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ServerAddressByClientCIDR": {
|
||||
"description": "ServerAddressByClientCIDR helps the client to determine the server address that they should use, depending on the clientCIDR that they match.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"clientCIDR",
|
||||
"serverAddress"
|
||||
],
|
||||
"properties": {
|
||||
"clientCIDR": {
|
||||
"description": "The CIDR with which clients can match their IP to figure out the server address that they should use.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"serverAddress": {
|
||||
"description": "Address of this server, suitable for a client that matches the above CIDR. This can be a hostname, hostname:port, IP or IP:port.",
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
40
api/openapi-spec/v3/logs_openapi.json
Normal file
40
api/openapi-spec/v3/logs_openapi.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/logs/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"logs"
|
||||
],
|
||||
"operationId": "logFileListHandler",
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/logs/{logpath}": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"logs"
|
||||
],
|
||||
"operationId": "logFileHandler",
|
||||
"responses": {}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "logpath",
|
||||
"in": "path",
|
||||
"description": "path to the log",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string",
|
||||
"uniqueItems": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"components": {}
|
||||
}
|
31
api/openapi-spec/v3/openid__v1__jwks_openapi.json
Normal file
31
api/openapi-spec/v3/openid__v1__jwks_openapi.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/openid/v1/jwks/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"openid"
|
||||
],
|
||||
"description": "get service account issuer OpenID JSON Web Key Set (contains public token verification keys)",
|
||||
"operationId": "getServiceAccountIssuerOpenIDKeyset",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/jwk-set+json": {
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {}
|
||||
}
|
87
api/openapi-spec/v3/version_openapi.json
Normal file
87
api/openapi-spec/v3/version_openapi.json
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Kubernetes",
|
||||
"version": "v1.23.0"
|
||||
},
|
||||
"paths": {
|
||||
"/version/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"version"
|
||||
],
|
||||
"description": "get the code version",
|
||||
"operationId": "getCodeVersion",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/io.k8s.apimachinery.pkg.version.Info"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"io.k8s.apimachinery.pkg.version.Info": {
|
||||
"description": "Info contains versioning information. how we'll want to distribute that information.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"major",
|
||||
"minor",
|
||||
"gitVersion",
|
||||
"gitCommit",
|
||||
"gitTreeState",
|
||||
"buildDate",
|
||||
"goVersion",
|
||||
"compiler",
|
||||
"platform"
|
||||
],
|
||||
"properties": {
|
||||
"buildDate": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"compiler": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"gitCommit": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"gitTreeState": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"gitVersion": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"goVersion": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"major": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"minor": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"platform": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -96,10 +96,21 @@ if ! kube::util::wait_for_url "https://${API_HOST}:${API_PORT}/healthz" "apiserv
|
||||
exit 1
|
||||
fi
|
||||
|
||||
kube::log::status "Updating " "${OPENAPI_ROOT_DIR}"
|
||||
kube::log::status "Updating " "${OPENAPI_ROOT_DIR} for OpenAPI v2"
|
||||
|
||||
curl -w "\n" -kfsS -H 'Authorization: Bearer dummy_token' "https://${API_HOST}:${API_PORT}/openapi/v2" | jq -S '.info.version="unversioned"' > "${OPENAPI_ROOT_DIR}/swagger.json"
|
||||
|
||||
kube::log::status "Updating " "${OPENAPI_ROOT_DIR}/v3 for OpenAPI v3"
|
||||
|
||||
mkdir -p "${OPENAPI_ROOT_DIR}/v3"
|
||||
curl -w "\n" -kfsS -H 'Authorization: Bearer dummy_token' "https://${API_HOST}:${API_PORT}/openapi/v3" | jq '.Paths' | jq -r '.[]' | while read -r group; do
|
||||
kube::log::status "Updating OpenAPI spec for group ${group}"
|
||||
OPENAPI_FILENAME="${group}_openapi.json"
|
||||
OPENAPI_FILENAME_ESCAPED="${OPENAPI_FILENAME//\//__}"
|
||||
OPENAPI_PATH="${OPENAPI_ROOT_DIR}/v3/${OPENAPI_FILENAME_ESCAPED}"
|
||||
curl -w "\n" -kfsS -H 'Authorization: Bearer dummy_token' "https://${API_HOST}:${API_PORT}/openapi/v3/{$group}" | jq . > "$OPENAPI_PATH"
|
||||
done
|
||||
|
||||
kube::log::status "SUCCESS"
|
||||
|
||||
# ex: ts=2 sw=2 et filetype=sh
|
||||
|
@@ -32,13 +32,15 @@ kube::etcd::install
|
||||
make -C "${KUBE_ROOT}" WHAT=cmd/kube-apiserver
|
||||
|
||||
SPECROOT="${KUBE_ROOT}/api/openapi-spec"
|
||||
SPECV3PATH="${SPECROOT}/v3"
|
||||
TMP_SPECROOT="${KUBE_ROOT}/_tmp/openapi-spec"
|
||||
_tmp="${KUBE_ROOT}/_tmp"
|
||||
|
||||
mkdir -p "${_tmp}"
|
||||
cp -a "${SPECROOT}" "${TMP_SPECROOT}"
|
||||
trap 'cp -a ${TMP_SPECROOT} ${SPECROOT}/..; rm -rf ${_tmp}' EXIT SIGINT
|
||||
rm "${SPECROOT}"/*
|
||||
rm -r "${SPECROOT:?}"/*
|
||||
mkdir -p "${SPECV3PATH}"
|
||||
cp "${TMP_SPECROOT}/README.md" "${SPECROOT}/README.md"
|
||||
|
||||
"${KUBE_ROOT}/hack/update-openapi-spec.sh"
|
||||
|
@@ -32,6 +32,7 @@ import (
|
||||
"k8s.io/apiextensions-apiserver/pkg/controller/finalizer"
|
||||
"k8s.io/apiextensions-apiserver/pkg/controller/nonstructuralschema"
|
||||
openapicontroller "k8s.io/apiextensions-apiserver/pkg/controller/openapi"
|
||||
openapiv3controller "k8s.io/apiextensions-apiserver/pkg/controller/openapiv3"
|
||||
"k8s.io/apiextensions-apiserver/pkg/controller/status"
|
||||
"k8s.io/apiextensions-apiserver/pkg/registry/customresourcedefinition"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -41,10 +42,12 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apimachinery/pkg/version"
|
||||
"k8s.io/apiserver/pkg/endpoints/discovery"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
genericregistry "k8s.io/apiserver/pkg/registry/generic"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
serverstorage "k8s.io/apiserver/pkg/server/storage"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/apiserver/pkg/util/webhook"
|
||||
)
|
||||
|
||||
@@ -218,6 +221,10 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
|
||||
crdHandler,
|
||||
)
|
||||
openapiController := openapicontroller.NewController(s.Informers.Apiextensions().V1().CustomResourceDefinitions())
|
||||
var openapiv3Controller *openapiv3controller.Controller
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.OpenAPIV3) {
|
||||
openapiv3Controller = openapiv3controller.NewController(s.Informers.Apiextensions().V1().CustomResourceDefinitions())
|
||||
}
|
||||
|
||||
s.GenericAPIServer.AddPostStartHookOrDie("start-apiextensions-informers", func(context genericapiserver.PostStartHookContext) error {
|
||||
s.Informers.Start(context.StopCh)
|
||||
@@ -230,6 +237,9 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
|
||||
// and StaticOpenAPISpec are both null. In that case we don't run the CRD OpenAPI controller.
|
||||
if s.GenericAPIServer.OpenAPIVersionedService != nil && s.GenericAPIServer.StaticOpenAPISpec != nil {
|
||||
go openapiController.Run(s.GenericAPIServer.StaticOpenAPISpec, s.GenericAPIServer.OpenAPIVersionedService, context.StopCh)
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.OpenAPIV3) {
|
||||
go openapiv3Controller.Run(s.GenericAPIServer.OpenAPIV3VersionedService, context.StopCh)
|
||||
}
|
||||
}
|
||||
|
||||
go namingController.Run(context.StopCh)
|
||||
|
@@ -1361,7 +1361,8 @@ func buildOpenAPIModelsForApply(staticOpenAPISpec *spec.Swagger, crd *apiextensi
|
||||
specs := []*spec.Swagger{}
|
||||
for _, v := range crd.Spec.Versions {
|
||||
// Defaults are not pruned here, but before being served.
|
||||
s, err := builder.BuildSwagger(crd, v.Name, builder.Options{V2: false, StripValueValidation: true, StripNullable: true, AllowNonStructural: false})
|
||||
// See flag description in builder.go for flag usage
|
||||
s, err := builder.BuildOpenAPIV2(crd, v.Name, builder.Options{V2: true, SkipFilterSchemaForKubectlOpenAPIV2Validation: true, StripValueValidation: true, StripNullable: true, AllowNonStructural: false})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -43,7 +43,9 @@ import (
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
utilopenapi "k8s.io/apiserver/pkg/util/openapi"
|
||||
openapibuilder "k8s.io/kube-openapi/pkg/builder"
|
||||
"k8s.io/kube-openapi/pkg/builder3"
|
||||
"k8s.io/kube-openapi/pkg/common"
|
||||
"k8s.io/kube-openapi/pkg/spec3"
|
||||
"k8s.io/kube-openapi/pkg/util"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
@@ -52,10 +54,13 @@ const (
|
||||
// Reference and Go types for built-in metadata
|
||||
objectMetaSchemaRef = "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"
|
||||
listMetaSchemaRef = "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ListMeta"
|
||||
listMetaType = "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"
|
||||
typeMetaType = "k8s.io/apimachinery/pkg/apis/meta/v1.TypeMeta"
|
||||
|
||||
definitionPrefix = "#/definitions/"
|
||||
listMetaType = "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"
|
||||
typeMetaType = "k8s.io/apimachinery/pkg/apis/meta/v1.TypeMeta"
|
||||
objectMetaType = "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"
|
||||
|
||||
definitionPrefix = "#/definitions/"
|
||||
v3DefinitionPrefix = "#/components/schemas/"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -66,6 +71,15 @@ var (
|
||||
namespaceToken = "{namespace}"
|
||||
)
|
||||
|
||||
// The path for definitions in OpenAPI v2 and v3 are different. Translate the path if necessary
|
||||
// The provided schemaRef uses a v2 prefix and is converted to v3 if the v2 bool is false
|
||||
func refForOpenAPIVersion(schemaRef string, v2 bool) string {
|
||||
if v2 {
|
||||
return schemaRef
|
||||
}
|
||||
return strings.Replace(schemaRef, definitionPrefix, v3DefinitionPrefix, 1)
|
||||
}
|
||||
|
||||
var definitions map[string]common.OpenAPIDefinition
|
||||
var buildDefinitions sync.Once
|
||||
var namer *openapi.DefinitionNamer
|
||||
@@ -75,6 +89,12 @@ type Options struct {
|
||||
// Convert to OpenAPI v2.
|
||||
V2 bool
|
||||
|
||||
// Only takes effect if the flag and V2 and both set to true. If the condition is reached,
|
||||
// publish OpenAPI V2 but skip running the spec through ToStructuralOpenAPIV2
|
||||
// This prevents XPreserveUnknownFields:true fields from being cleared
|
||||
// Used only by server side apply
|
||||
SkipFilterSchemaForKubectlOpenAPIV2Validation bool
|
||||
|
||||
// Strip value validation.
|
||||
StripValueValidation bool
|
||||
|
||||
@@ -85,8 +105,7 @@ type Options struct {
|
||||
AllowNonStructural bool
|
||||
}
|
||||
|
||||
// BuildSwagger builds swagger for the given crd in the given version
|
||||
func BuildSwagger(crd *apiextensionsv1.CustomResourceDefinition, version string, opts Options) (*spec.Swagger, error) {
|
||||
func generateBuilder(crd *apiextensionsv1.CustomResourceDefinition, version string, opts Options) (*builder, error) {
|
||||
var schema *structuralschema.Structural
|
||||
s, err := apiextensionshelpers.GetSchemaForVersion(crd, version)
|
||||
if err != nil {
|
||||
@@ -122,7 +141,7 @@ func BuildSwagger(crd *apiextensionsv1.CustomResourceDefinition, version string,
|
||||
// comes from function registerResourceHandlers() in k8s.io/apiserver.
|
||||
// Alternatives are either (ideally) refactoring registerResourceHandlers() to
|
||||
// reuse the code, or faking an APIInstaller for CR to feed to registerResourceHandlers().
|
||||
b := newBuilder(crd, version, schema, opts.V2)
|
||||
b := newBuilder(crd, version, schema, opts)
|
||||
|
||||
// Sample response types for building web service
|
||||
sample := &CRDCanonicalTypeNamer{
|
||||
@@ -173,13 +192,26 @@ func BuildSwagger(crd *apiextensionsv1.CustomResourceDefinition, version string,
|
||||
for _, route := range routes {
|
||||
b.ws.Route(route)
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
openAPISpec, err := openapibuilder.BuildOpenAPISpec([]*restful.WebService{b.ws}, b.getOpenAPIConfig())
|
||||
func BuildOpenAPIV3(crd *apiextensionsv1.CustomResourceDefinition, version string, opts Options) (*spec3.OpenAPI, error) {
|
||||
b, err := generateBuilder(crd, version, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return openAPISpec, nil
|
||||
return builder3.BuildOpenAPISpec([]*restful.WebService{b.ws}, b.getOpenAPIConfig(false))
|
||||
}
|
||||
|
||||
// BuildOpenAPIV2 builds OpenAPI v2 for the given crd in the given version
|
||||
func BuildOpenAPIV2(crd *apiextensionsv1.CustomResourceDefinition, version string, opts Options) (*spec.Swagger, error) {
|
||||
b, err := generateBuilder(crd, version, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return openapibuilder.BuildOpenAPISpec([]*restful.WebService{b.ws}, b.getOpenAPIConfig(true))
|
||||
}
|
||||
|
||||
// Implements CanonicalTypeNamer
|
||||
@@ -349,26 +381,26 @@ func (b *builder) buildRoute(root, path, httpMethod, actionVerb, operationVerb s
|
||||
|
||||
// buildKubeNative builds input schema with Kubernetes' native object meta, type meta and
|
||||
// extensions
|
||||
func (b *builder) buildKubeNative(schema *structuralschema.Structural, v2 bool, crdPreserveUnknownFields bool) (ret *spec.Schema) {
|
||||
func (b *builder) buildKubeNative(schema *structuralschema.Structural, opts Options, crdPreserveUnknownFields bool) (ret *spec.Schema) {
|
||||
// only add properties if we have a schema. Otherwise, kubectl would (wrongly) assume additionalProperties=false
|
||||
// and forbid anything outside of apiVersion, kind and metadata. We have to fix kubectl to stop doing this, e.g. by
|
||||
// adding additionalProperties=true support to explicitly allow additional fields.
|
||||
// TODO: fix kubectl to understand additionalProperties=true
|
||||
if schema == nil || (v2 && (schema.XPreserveUnknownFields || crdPreserveUnknownFields)) {
|
||||
if schema == nil || ((opts.V2 && !opts.SkipFilterSchemaForKubectlOpenAPIV2Validation) && (schema.XPreserveUnknownFields || crdPreserveUnknownFields)) {
|
||||
ret = &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{Type: []string{"object"}},
|
||||
}
|
||||
// no, we cannot add more properties here, not even TypeMeta/ObjectMeta because kubectl will complain about
|
||||
// unknown fields for anything else.
|
||||
} else {
|
||||
if v2 {
|
||||
if opts.V2 && !opts.SkipFilterSchemaForKubectlOpenAPIV2Validation {
|
||||
schema = openapiv2.ToStructuralOpenAPIV2(schema)
|
||||
}
|
||||
|
||||
ret = schema.ToKubeOpenAPI()
|
||||
ret.SetProperty("metadata", *spec.RefSchema(objectMetaSchemaRef).
|
||||
WithDescription(swaggerPartialObjectMetadataDescriptions["metadata"]))
|
||||
addTypeMetaProperties(ret)
|
||||
addEmbeddedProperties(ret, v2)
|
||||
ret.SetProperty("metadata", *spec.RefSchema(refForOpenAPIVersion(objectMetaSchemaRef, opts.V2)).WithDescription(swaggerPartialObjectMetadataDescriptions["metadata"]))
|
||||
addTypeMetaProperties(ret, opts.V2)
|
||||
addEmbeddedProperties(ret, opts)
|
||||
}
|
||||
ret.AddExtension(endpoints.ROUTE_META_GVK, []interface{}{
|
||||
map[string]interface{}{
|
||||
@@ -381,36 +413,36 @@ func (b *builder) buildKubeNative(schema *structuralschema.Structural, v2 bool,
|
||||
return ret
|
||||
}
|
||||
|
||||
func addEmbeddedProperties(s *spec.Schema, v2 bool) {
|
||||
func addEmbeddedProperties(s *spec.Schema, opts Options) {
|
||||
if s == nil {
|
||||
return
|
||||
}
|
||||
|
||||
for k := range s.Properties {
|
||||
v := s.Properties[k]
|
||||
addEmbeddedProperties(&v, v2)
|
||||
addEmbeddedProperties(&v, opts)
|
||||
s.Properties[k] = v
|
||||
}
|
||||
if s.Items != nil {
|
||||
addEmbeddedProperties(s.Items.Schema, v2)
|
||||
addEmbeddedProperties(s.Items.Schema, opts)
|
||||
}
|
||||
if s.AdditionalProperties != nil {
|
||||
addEmbeddedProperties(s.AdditionalProperties.Schema, v2)
|
||||
addEmbeddedProperties(s.AdditionalProperties.Schema, opts)
|
||||
}
|
||||
|
||||
if isTrue, ok := s.VendorExtensible.Extensions.GetBool("x-kubernetes-preserve-unknown-fields"); ok && isTrue && v2 {
|
||||
if isTrue, ok := s.VendorExtensible.Extensions.GetBool("x-kubernetes-preserve-unknown-fields"); ok && isTrue && opts.V2 && !opts.SkipFilterSchemaForKubectlOpenAPIV2Validation {
|
||||
// don't add metadata properties if we're publishing to openapi v2 and are allowing unknown fields.
|
||||
// adding these metadata properties makes kubectl refuse to validate unknown fields.
|
||||
return
|
||||
}
|
||||
if isTrue, ok := s.VendorExtensible.Extensions.GetBool("x-kubernetes-embedded-resource"); ok && isTrue {
|
||||
s.SetProperty("apiVersion", withDescription(getDefinition(typeMetaType).SchemaProps.Properties["apiVersion"],
|
||||
s.SetProperty("apiVersion", withDescription(getDefinition(typeMetaType, opts.V2).SchemaProps.Properties["apiVersion"],
|
||||
"apiVersion defines the versioned schema of this representation of an object. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
|
||||
))
|
||||
s.SetProperty("kind", withDescription(getDefinition(typeMetaType).SchemaProps.Properties["kind"],
|
||||
s.SetProperty("kind", withDescription(getDefinition(typeMetaType, opts.V2).SchemaProps.Properties["kind"],
|
||||
"kind is a string value representing the type of this object. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
|
||||
))
|
||||
s.SetProperty("metadata", *spec.RefSchema(objectMetaSchemaRef).WithDescription(swaggerPartialObjectMetadataDescriptions["metadata"]))
|
||||
s.SetProperty("metadata", *spec.RefSchema(refForOpenAPIVersion(objectMetaSchemaRef, opts.V2)).WithDescription(swaggerPartialObjectMetadataDescriptions["metadata"]))
|
||||
|
||||
req := sets.NewString(s.Required...)
|
||||
if !req.Has("kind") {
|
||||
@@ -424,8 +456,8 @@ func addEmbeddedProperties(s *spec.Schema, v2 bool) {
|
||||
|
||||
// getDefinition gets definition for given Kubernetes type. This function is extracted from
|
||||
// kube-openapi builder logic
|
||||
func getDefinition(name string) spec.Schema {
|
||||
buildDefinitions.Do(buildDefinitionsFunc)
|
||||
func getDefinition(name string, v2 bool) spec.Schema {
|
||||
buildDefinitions.Do(generateBuildDefinitionsFunc(v2))
|
||||
return definitions[name].Schema
|
||||
}
|
||||
|
||||
@@ -433,31 +465,37 @@ func withDescription(s spec.Schema, desc string) spec.Schema {
|
||||
return *s.WithDescription(desc)
|
||||
}
|
||||
|
||||
func buildDefinitionsFunc() {
|
||||
namer = openapi.NewDefinitionNamer(runtime.NewScheme())
|
||||
definitions = utilopenapi.GetOpenAPIDefinitionsWithoutDisabledFeatures(generatedopenapi.GetOpenAPIDefinitions)(func(name string) spec.Ref {
|
||||
defName, _ := namer.GetDefinitionName(name)
|
||||
return spec.MustCreateRef(definitionPrefix + common.EscapeJsonPointer(defName))
|
||||
})
|
||||
func generateBuildDefinitionsFunc(v2 bool) func() {
|
||||
return func() {
|
||||
namer = openapi.NewDefinitionNamer(runtime.NewScheme())
|
||||
definitions = utilopenapi.GetOpenAPIDefinitionsWithoutDisabledFeatures(generatedopenapi.GetOpenAPIDefinitions)(func(name string) spec.Ref {
|
||||
defName, _ := namer.GetDefinitionName(name)
|
||||
prefix := v3DefinitionPrefix
|
||||
if v2 {
|
||||
prefix = definitionPrefix
|
||||
}
|
||||
return spec.MustCreateRef(prefix + common.EscapeJsonPointer(defName))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// addTypeMetaProperties adds Kubernetes-specific type meta properties to input schema:
|
||||
// apiVersion and kind
|
||||
func addTypeMetaProperties(s *spec.Schema) {
|
||||
s.SetProperty("apiVersion", getDefinition(typeMetaType).SchemaProps.Properties["apiVersion"])
|
||||
s.SetProperty("kind", getDefinition(typeMetaType).SchemaProps.Properties["kind"])
|
||||
func addTypeMetaProperties(s *spec.Schema, v2 bool) {
|
||||
s.SetProperty("apiVersion", getDefinition(typeMetaType, v2).SchemaProps.Properties["apiVersion"])
|
||||
s.SetProperty("kind", getDefinition(typeMetaType, v2).SchemaProps.Properties["kind"])
|
||||
}
|
||||
|
||||
// buildListSchema builds the list kind schema for the CRD
|
||||
func (b *builder) buildListSchema() *spec.Schema {
|
||||
func (b *builder) buildListSchema(v2 bool) *spec.Schema {
|
||||
name := definitionPrefix + util.ToRESTFriendlyName(fmt.Sprintf("%s/%s/%s", b.group, b.version, b.kind))
|
||||
doc := fmt.Sprintf("List of %s. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md", b.plural)
|
||||
s := new(spec.Schema).WithDescription(fmt.Sprintf("%s is a list of %s", b.listKind, b.kind)).
|
||||
WithRequired("items").
|
||||
SetProperty("items", *spec.ArrayProperty(spec.RefSchema(name)).WithDescription(doc)).
|
||||
SetProperty("metadata", *spec.RefSchema(listMetaSchemaRef).WithDescription(swaggerPartialObjectMetadataListDescriptions["metadata"]))
|
||||
SetProperty("metadata", *spec.RefSchema(refForOpenAPIVersion(listMetaSchemaRef, v2)).WithDescription(swaggerPartialObjectMetadataListDescriptions["metadata"]))
|
||||
|
||||
addTypeMetaProperties(s)
|
||||
addTypeMetaProperties(s, v2)
|
||||
s.AddExtension(endpoints.ROUTE_META_GVK, []map[string]string{
|
||||
{
|
||||
"group": b.group,
|
||||
@@ -469,7 +507,7 @@ func (b *builder) buildListSchema() *spec.Schema {
|
||||
}
|
||||
|
||||
// getOpenAPIConfig builds config which wires up generated definitions for kube-openapi to consume
|
||||
func (b *builder) getOpenAPIConfig() *common.Config {
|
||||
func (b *builder) getOpenAPIConfig(v2 bool) *common.Config {
|
||||
return &common.Config{
|
||||
ProtocolList: []string{"https"},
|
||||
Info: &spec.Info{
|
||||
@@ -487,13 +525,14 @@ func (b *builder) getOpenAPIConfig() *common.Config {
|
||||
},
|
||||
GetOperationIDAndTags: openapi.GetOperationIDAndTags,
|
||||
GetDefinitionName: func(name string) (string, spec.Extensions) {
|
||||
buildDefinitions.Do(buildDefinitionsFunc)
|
||||
buildDefinitions.Do(generateBuildDefinitionsFunc(v2))
|
||||
return namer.GetDefinitionName(name)
|
||||
},
|
||||
GetDefinitions: func(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
|
||||
def := utilopenapi.GetOpenAPIDefinitionsWithoutDisabledFeatures(generatedopenapi.GetOpenAPIDefinitions)(ref)
|
||||
def[fmt.Sprintf("%s/%s.%s", b.group, b.version, b.kind)] = common.OpenAPIDefinition{
|
||||
Schema: *b.schema,
|
||||
Schema: *b.schema,
|
||||
Dependencies: []string{objectMetaType},
|
||||
}
|
||||
def[fmt.Sprintf("%s/%s.%s", b.group, b.version, b.listKind)] = common.OpenAPIDefinition{
|
||||
Schema: *b.listSchema,
|
||||
@@ -503,7 +542,7 @@ func (b *builder) getOpenAPIConfig() *common.Config {
|
||||
}
|
||||
}
|
||||
|
||||
func newBuilder(crd *apiextensionsv1.CustomResourceDefinition, version string, schema *structuralschema.Structural, v2 bool) *builder {
|
||||
func newBuilder(crd *apiextensionsv1.CustomResourceDefinition, version string, schema *structuralschema.Structural, opts Options) *builder {
|
||||
b := &builder{
|
||||
schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{Type: []string{"object"}},
|
||||
@@ -522,8 +561,8 @@ func newBuilder(crd *apiextensionsv1.CustomResourceDefinition, version string, s
|
||||
}
|
||||
|
||||
// Pre-build schema with Kubernetes native properties
|
||||
b.schema = b.buildKubeNative(schema, v2, crd.Spec.PreserveUnknownFields)
|
||||
b.listSchema = b.buildListSchema()
|
||||
b.schema = b.buildKubeNative(schema, opts, crd.Spec.PreserveUnknownFields)
|
||||
b.listSchema = b.buildListSchema(opts.V2)
|
||||
|
||||
return b
|
||||
}
|
||||
|
@@ -45,37 +45,43 @@ func TestNewBuilder(t *testing.T) {
|
||||
wantedSchema string
|
||||
wantedItemsSchema string
|
||||
|
||||
v2 bool // produce OpenAPIv2
|
||||
v2 bool // produce OpenAPIv2
|
||||
skipFilterSchemaForKubectlOpenAPIV2Validation bool // produce OpenAPIv2 without going through the ToStructuralOpenAPIV2 path
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
"",
|
||||
`{"type":"object","x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`, `{"$ref":"#/definitions/io.k8s.bar.v1.Foo"}`,
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{"with properties",
|
||||
`{"type":"object","properties":{"spec":{"type":"object"},"status":{"type":"object"}}}`,
|
||||
`{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"$ref":"#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"},"spec":{"type":"object"},"status":{"type":"object"}},"x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||
`{"$ref":"#/definitions/io.k8s.bar.v1.Foo"}`,
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{"type only",
|
||||
`{"type":"object"}`,
|
||||
`{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"$ref":"#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"}},"x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||
`{"$ref":"#/definitions/io.k8s.bar.v1.Foo"}`,
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{"preserve unknown at root v2",
|
||||
`{"type":"object","x-kubernetes-preserve-unknown-fields":true}`,
|
||||
`{"type":"object","x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||
`{"$ref":"#/definitions/io.k8s.bar.v1.Foo"}`,
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{"preserve unknown at root v3",
|
||||
`{"type":"object","x-kubernetes-preserve-unknown-fields":true}`,
|
||||
`{"type":"object","x-kubernetes-preserve-unknown-fields":true,"properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"$ref":"#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"}},"x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||
`{"$ref":"#/definitions/io.k8s.bar.v1.Foo"}`,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
},
|
||||
{"with extensions",
|
||||
`
|
||||
@@ -179,6 +185,7 @@ func TestNewBuilder(t *testing.T) {
|
||||
}`,
|
||||
`{"$ref":"#/definitions/io.k8s.bar.v1.Foo"}`,
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{"with extensions as v3 schema",
|
||||
`
|
||||
@@ -344,7 +351,8 @@ func TestNewBuilder(t *testing.T) {
|
||||
"x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]
|
||||
}`,
|
||||
`{"$ref":"#/definitions/io.k8s.bar.v1.Foo"}`,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
@@ -384,7 +392,7 @@ func TestNewBuilder(t *testing.T) {
|
||||
},
|
||||
Scope: apiextensionsv1.NamespaceScoped,
|
||||
},
|
||||
}, "v1", schema, tt.v2)
|
||||
}, "v1", schema, Options{V2: tt.v2, SkipFilterSchemaForKubectlOpenAPIV2Validation: tt.skipFilterSchemaForKubectlOpenAPIV2Validation})
|
||||
|
||||
var wantedSchema, wantedItemsSchema spec.Schema
|
||||
if err := json.Unmarshal([]byte(tt.wantedSchema), &wantedSchema); err != nil {
|
||||
@@ -500,7 +508,7 @@ func TestCRDRouteParameterBuilder(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
swagger, err := BuildSwagger(testNamespacedCRD, testCRDVersion, Options{V2: true})
|
||||
swagger, err := BuildOpenAPIV2(testNamespacedCRD, testCRDVersion, Options{V2: true})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(testCase.paths), len(swagger.Paths.Paths), testCase.scope)
|
||||
for path, expected := range testCase.paths {
|
||||
@@ -567,7 +575,7 @@ func schemaDiff(a, b *spec.Schema) string {
|
||||
return diff.StringDiff(string(as), string(bs))
|
||||
}
|
||||
|
||||
func TestBuildSwagger(t *testing.T) {
|
||||
func TestBuildOpenAPIV2(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
schema string
|
||||
@@ -622,7 +630,7 @@ func TestBuildSwagger(t *testing.T) {
|
||||
`{"type":"object","properties":{"foo":{"type":"string","oneOf":[{"pattern":"a"},{"pattern":"b"}]}}}`,
|
||||
nil,
|
||||
`{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"$ref":"#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"},"foo":{"type":"string","oneOf":[{"pattern":"a"},{"pattern":"b"}]}},"x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||
Options{V2: false},
|
||||
Options{V2: true, SkipFilterSchemaForKubectlOpenAPIV2Validation: true},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
@@ -642,7 +650,7 @@ func TestBuildSwagger(t *testing.T) {
|
||||
}
|
||||
|
||||
// TODO: mostly copied from the test above. reuse code to cleanup
|
||||
got, err := BuildSwagger(&apiextensionsv1.CustomResourceDefinition{
|
||||
got, err := BuildOpenAPIV2(&apiextensionsv1.CustomResourceDefinition{
|
||||
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||
Group: "bar.k8s.io",
|
||||
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||
@@ -691,3 +699,106 @@ func TestBuildSwagger(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildOpenAPIV3(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
schema string
|
||||
preserveUnknownFields *bool
|
||||
wantedSchema string
|
||||
opts Options
|
||||
}{
|
||||
{
|
||||
"nil",
|
||||
"",
|
||||
nil,
|
||||
`{"type":"object","x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||
Options{},
|
||||
},
|
||||
{
|
||||
"with properties",
|
||||
`{"type":"object","properties":{"spec":{"type":"object"},"status":{"type":"object"}}}`,
|
||||
nil,
|
||||
`{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"$ref":"#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"},"spec":{"type":"object"},"status":{"type":"object"}},"x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||
Options{},
|
||||
},
|
||||
{
|
||||
"with v3 nullable field",
|
||||
`{"type":"object","properties":{"spec":{"type":"object", "nullable": true},"status":{"type":"object"}}}`,
|
||||
nil,
|
||||
`{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"$ref":"#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"},"spec":{"type":"object", "nullable": true},"status":{"type":"object"}},"x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||
Options{},
|
||||
},
|
||||
{
|
||||
"with default not pruned for v3",
|
||||
`{"type":"object","properties":{"spec":{"type":"object","properties":{"field":{"type":"string","default":"foo"}}},"status":{"type":"object"}}}`,
|
||||
nil,
|
||||
`{"type":"object","properties":{"apiVersion":{"type":"string"},"kind":{"type":"string"},"metadata":{"$ref":"#/components/schemas/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"},"spec":{"type":"object","properties":{"field":{"type":"string","default":"foo"}}},"status":{"type":"object"}},"x-kubernetes-group-version-kind":[{"group":"bar.k8s.io","kind":"Foo","version":"v1"}]}`,
|
||||
Options{},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var validation *apiextensionsv1.CustomResourceValidation
|
||||
if len(tt.schema) > 0 {
|
||||
v1Schema := &apiextensionsv1.JSONSchemaProps{}
|
||||
if err := json.Unmarshal([]byte(tt.schema), &v1Schema); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
validation = &apiextensionsv1.CustomResourceValidation{
|
||||
OpenAPIV3Schema: v1Schema,
|
||||
}
|
||||
}
|
||||
if tt.preserveUnknownFields != nil && *tt.preserveUnknownFields {
|
||||
validation.OpenAPIV3Schema.XPreserveUnknownFields = utilpointer.BoolPtr(true)
|
||||
}
|
||||
|
||||
got, err := BuildOpenAPIV3(&apiextensionsv1.CustomResourceDefinition{
|
||||
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
||||
Group: "bar.k8s.io",
|
||||
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
||||
{
|
||||
Name: "v1",
|
||||
Schema: validation,
|
||||
},
|
||||
},
|
||||
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
||||
Plural: "foos",
|
||||
Singular: "foo",
|
||||
Kind: "Foo",
|
||||
ListKind: "FooList",
|
||||
},
|
||||
Scope: apiextensionsv1.NamespaceScoped,
|
||||
},
|
||||
}, "v1", tt.opts)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var wantedSchema spec.Schema
|
||||
if err := json.Unmarshal([]byte(tt.wantedSchema), &wantedSchema); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
gotSchema := *got.Components.Schemas["io.k8s.bar.v1.Foo"]
|
||||
gotProperties := properties(gotSchema.Properties)
|
||||
wantedProperties := properties(wantedSchema.Properties)
|
||||
if !gotProperties.Equal(wantedProperties) {
|
||||
t.Fatalf("unexpected properties, got: %s, expected: %s", gotProperties.List(), wantedProperties.List())
|
||||
}
|
||||
|
||||
// wipe out TypeMeta/ObjectMeta content, with those many lines of descriptions. We trust that they match here.
|
||||
for _, metaField := range []string{"kind", "apiVersion", "metadata"} {
|
||||
if _, found := gotSchema.Properties["kind"]; found {
|
||||
prop := gotSchema.Properties[metaField]
|
||||
prop.Description = ""
|
||||
gotSchema.Properties[metaField] = prop
|
||||
}
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(&wantedSchema, &gotSchema) {
|
||||
t.Errorf("unexpected schema: %s\nwant = %#v\ngot = %#v", schemaDiff(&wantedSchema, &gotSchema), &wantedSchema, &gotSchema)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@@ -17,7 +17,9 @@ limitations under the License.
|
||||
package builder
|
||||
|
||||
import (
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kube-openapi/pkg/aggregator"
|
||||
"k8s.io/kube-openapi/pkg/spec3"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
@@ -79,3 +81,51 @@ func mergeSpec(dest, source *spec.Swagger) {
|
||||
dest.Paths.Paths[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
// MergeSpecsV3 merges OpenAPI v3 specs for CRDs
|
||||
// For V3, the static spec is never merged with the individual CRD specs so no conflict resolution is necessary
|
||||
func MergeSpecsV3(crdSpecs ...*spec3.OpenAPI) (*spec3.OpenAPI, error) {
|
||||
// create shallow copy of staticSpec, but replace paths and definitions because we modify them.
|
||||
crdSpec := &spec3.OpenAPI{}
|
||||
if len(crdSpecs) > 0 {
|
||||
crdSpec.Version = crdSpecs[0].Version
|
||||
crdSpec.Info = crdSpecs[0].Info
|
||||
}
|
||||
for _, s := range crdSpecs {
|
||||
// merge specs without checking conflicts, since the naming controller prevents
|
||||
// conflicts between user-defined CRDs
|
||||
mergeSpecV3(crdSpec, s)
|
||||
}
|
||||
|
||||
return crdSpec, nil
|
||||
}
|
||||
|
||||
// mergeSpecV3 copies paths and definitions from source to dest, mutating dest, but not source.
|
||||
// We assume that conflicts do not matter.
|
||||
func mergeSpecV3(dest, source *spec3.OpenAPI) {
|
||||
if source == nil || source.Paths == nil {
|
||||
return
|
||||
}
|
||||
if dest.Paths == nil {
|
||||
dest.Paths = &spec3.Paths{}
|
||||
}
|
||||
|
||||
for k, v := range source.Components.Schemas {
|
||||
if dest.Components == nil {
|
||||
dest.Components = &spec3.Components{}
|
||||
}
|
||||
if dest.Components.Schemas == nil {
|
||||
dest.Components.Schemas = map[string]*spec.Schema{}
|
||||
}
|
||||
if _, exists := dest.Components.Schemas[k]; exists {
|
||||
klog.Warningf("Should not happen: OpenAPI V3 merge schema conflict on %s", k)
|
||||
}
|
||||
dest.Components.Schemas[k] = v
|
||||
}
|
||||
for k, v := range source.Paths.Paths {
|
||||
if dest.Paths.Paths == nil {
|
||||
dest.Paths.Paths = map[string]*spec3.Path{}
|
||||
}
|
||||
dest.Paths.Paths[k] = v
|
||||
}
|
||||
}
|
||||
|
@@ -202,7 +202,7 @@ func buildVersionSpecs(crd *apiextensionsv1.CustomResourceDefinition, oldSpecs m
|
||||
continue
|
||||
}
|
||||
// Defaults are not pruned here, but before being served.
|
||||
spec, err := builder.BuildSwagger(crd, v.Name, builder.Options{V2: true})
|
||||
spec, err := builder.BuildOpenAPIV2(crd, v.Name, builder.Options{V2: true})
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package openapiv3
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kube-openapi/pkg/handler3"
|
||||
"k8s.io/kube-openapi/pkg/spec3"
|
||||
|
||||
apiextensionshelpers "k8s.io/apiextensions-apiserver/pkg/apihelpers"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
informers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions/apiextensions/v1"
|
||||
listers "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1"
|
||||
"k8s.io/apiextensions-apiserver/pkg/controller/openapi/builder"
|
||||
)
|
||||
|
||||
// Controller watches CustomResourceDefinitions and publishes OpenAPI v3
|
||||
type Controller struct {
|
||||
crdLister listers.CustomResourceDefinitionLister
|
||||
crdsSynced cache.InformerSynced
|
||||
|
||||
// To allow injection for testing.
|
||||
syncFn func(string) error
|
||||
|
||||
queue workqueue.RateLimitingInterface
|
||||
|
||||
openAPIV3Service *handler3.OpenAPIService
|
||||
|
||||
// specs per version and per CRD name
|
||||
lock sync.Mutex
|
||||
specsByGVandName map[schema.GroupVersion]map[string]*spec3.OpenAPI
|
||||
}
|
||||
|
||||
// NewController creates a new Controller with input CustomResourceDefinition informer
|
||||
func NewController(crdInformer informers.CustomResourceDefinitionInformer) *Controller {
|
||||
c := &Controller{
|
||||
crdLister: crdInformer.Lister(),
|
||||
crdsSynced: crdInformer.Informer().HasSynced,
|
||||
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "crd_openapi_v3_controller"),
|
||||
specsByGVandName: map[schema.GroupVersion]map[string]*spec3.OpenAPI{},
|
||||
}
|
||||
|
||||
crdInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: c.addCustomResourceDefinition,
|
||||
UpdateFunc: c.updateCustomResourceDefinition,
|
||||
DeleteFunc: c.deleteCustomResourceDefinition,
|
||||
})
|
||||
|
||||
c.syncFn = c.sync
|
||||
return c
|
||||
}
|
||||
|
||||
// Run sets openAPIAggregationManager and starts workers
|
||||
func (c *Controller) Run(openAPIV3Service *handler3.OpenAPIService, stopCh <-chan struct{}) {
|
||||
defer utilruntime.HandleCrash()
|
||||
defer c.queue.ShutDown()
|
||||
defer klog.Infof("Shutting down OpenAPI V3 controller")
|
||||
|
||||
klog.Infof("Starting OpenAPI V3 controller")
|
||||
|
||||
c.openAPIV3Service = openAPIV3Service
|
||||
|
||||
if !cache.WaitForCacheSync(stopCh, c.crdsSynced) {
|
||||
utilruntime.HandleError(fmt.Errorf("timed out waiting for caches to sync"))
|
||||
return
|
||||
}
|
||||
|
||||
crds, err := c.crdLister.List(labels.Everything())
|
||||
if err != nil {
|
||||
utilruntime.HandleError(fmt.Errorf("failed to initially list all CRDs: %v", err))
|
||||
return
|
||||
}
|
||||
for _, crd := range crds {
|
||||
if !apiextensionshelpers.IsCRDConditionTrue(crd, apiextensionsv1.Established) {
|
||||
continue
|
||||
}
|
||||
for _, v := range crd.Spec.Versions {
|
||||
if !v.Served {
|
||||
continue
|
||||
}
|
||||
c.buildV3Spec(crd, crd.Name, v.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// only start one worker thread since its a slow moving API
|
||||
go wait.Until(c.runWorker, time.Second, stopCh)
|
||||
|
||||
<-stopCh
|
||||
}
|
||||
|
||||
func (c *Controller) runWorker() {
|
||||
for c.processNextWorkItem() {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) processNextWorkItem() bool {
|
||||
key, quit := c.queue.Get()
|
||||
if quit {
|
||||
return false
|
||||
}
|
||||
defer c.queue.Done(key)
|
||||
|
||||
// log slow aggregations
|
||||
start := time.Now()
|
||||
defer func() {
|
||||
elapsed := time.Since(start)
|
||||
if elapsed > time.Second {
|
||||
klog.Warningf("slow openapi aggregation of %q: %s", key.(string), elapsed)
|
||||
}
|
||||
}()
|
||||
|
||||
err := c.syncFn(key.(string))
|
||||
if err == nil {
|
||||
c.queue.Forget(key)
|
||||
return true
|
||||
}
|
||||
|
||||
utilruntime.HandleError(fmt.Errorf("%v failed with: %v", key, err))
|
||||
c.queue.AddRateLimited(key)
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *Controller) sync(name string) error {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
||||
crd, err := c.crdLister.Get(name)
|
||||
if err != nil && !errors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if errors.IsNotFound(err) || !apiextensionshelpers.IsCRDConditionTrue(crd, apiextensionsv1.Established) {
|
||||
c.deleteCRD(name)
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, v := range crd.Spec.Versions {
|
||||
if !v.Served {
|
||||
continue
|
||||
}
|
||||
c.buildV3Spec(crd, name, v.Name)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) deleteCRD(name string) {
|
||||
for gv, crdListForGV := range c.specsByGVandName {
|
||||
_, needOpenAPIUpdate := crdListForGV[name]
|
||||
if needOpenAPIUpdate {
|
||||
delete(crdListForGV, name)
|
||||
if len(crdListForGV) == 0 {
|
||||
delete(c.specsByGVandName, gv)
|
||||
}
|
||||
c.updateGroupVersion(gv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) updateGroupVersion(gv schema.GroupVersion) error {
|
||||
if _, ok := c.specsByGVandName[gv]; !ok {
|
||||
c.openAPIV3Service.DeleteGroupVersion(groupVersionToOpenAPIV3Path(gv))
|
||||
return nil
|
||||
}
|
||||
|
||||
var specs []*spec3.OpenAPI
|
||||
for _, spec := range c.specsByGVandName[gv] {
|
||||
specs = append(specs, spec)
|
||||
}
|
||||
|
||||
mergedSpec, err := builder.MergeSpecsV3(specs...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to merge specs: %v", err)
|
||||
}
|
||||
|
||||
c.openAPIV3Service.UpdateGroupVersion(groupVersionToOpenAPIV3Path(gv), mergedSpec)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) updateCRDSpec(crd *apiextensionsv1.CustomResourceDefinition, name, versionName string, v3 *spec3.OpenAPI) error {
|
||||
gv := schema.GroupVersion{
|
||||
Group: crd.Spec.Group,
|
||||
Version: versionName,
|
||||
}
|
||||
|
||||
_, ok := c.specsByGVandName[gv]
|
||||
if !ok {
|
||||
c.specsByGVandName[gv] = map[string]*spec3.OpenAPI{}
|
||||
}
|
||||
|
||||
oldSpec, ok := c.specsByGVandName[gv][name]
|
||||
if ok {
|
||||
if reflect.DeepEqual(oldSpec, v3) {
|
||||
// no changes to CRD
|
||||
return nil
|
||||
}
|
||||
}
|
||||
c.specsByGVandName[gv][name] = v3
|
||||
|
||||
return c.updateGroupVersion(gv)
|
||||
}
|
||||
|
||||
func (c *Controller) buildV3Spec(crd *apiextensionsv1.CustomResourceDefinition, name, versionName string) error {
|
||||
v3, err := builder.BuildOpenAPIV3(crd, versionName, builder.Options{V2: false})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.updateCRDSpec(crd, name, versionName, v3)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Controller) addCustomResourceDefinition(obj interface{}) {
|
||||
castObj := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
klog.V(4).Infof("Adding customresourcedefinition %s", castObj.Name)
|
||||
c.enqueue(castObj)
|
||||
}
|
||||
|
||||
func (c *Controller) updateCustomResourceDefinition(oldObj, newObj interface{}) {
|
||||
castNewObj := newObj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
klog.V(4).Infof("Updating customresourcedefinition %s", castNewObj.Name)
|
||||
c.enqueue(castNewObj)
|
||||
}
|
||||
|
||||
func (c *Controller) deleteCustomResourceDefinition(obj interface{}) {
|
||||
castObj, ok := obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
if !ok {
|
||||
tombstone, ok := obj.(cache.DeletedFinalStateUnknown)
|
||||
if !ok {
|
||||
klog.Errorf("Couldn't get object from tombstone %#v", obj)
|
||||
return
|
||||
}
|
||||
castObj, ok = tombstone.Obj.(*apiextensionsv1.CustomResourceDefinition)
|
||||
if !ok {
|
||||
klog.Errorf("Tombstone contained object that is not expected %#v", obj)
|
||||
return
|
||||
}
|
||||
}
|
||||
klog.V(4).Infof("Deleting customresourcedefinition %q", castObj.Name)
|
||||
c.enqueue(castObj)
|
||||
}
|
||||
|
||||
func (c *Controller) enqueue(obj *apiextensionsv1.CustomResourceDefinition) {
|
||||
c.queue.Add(obj.Name)
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package openapiv3
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
func groupVersionToOpenAPIV3Path(gv schema.GroupVersion) string {
|
||||
return "apis/" + gv.Group + "/" + gv.Version
|
||||
}
|
@@ -49,9 +49,10 @@ import (
|
||||
utilopenapi "k8s.io/apiserver/pkg/util/openapi"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/klog/v2"
|
||||
openapibuilder "k8s.io/kube-openapi/pkg/builder"
|
||||
openapibuilder2 "k8s.io/kube-openapi/pkg/builder"
|
||||
openapicommon "k8s.io/kube-openapi/pkg/common"
|
||||
"k8s.io/kube-openapi/pkg/handler"
|
||||
"k8s.io/kube-openapi/pkg/handler3"
|
||||
openapiutil "k8s.io/kube-openapi/pkg/util"
|
||||
openapiproto "k8s.io/kube-openapi/pkg/util/proto"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
@@ -144,6 +145,10 @@ type GenericAPIServer struct {
|
||||
// It is set during PrepareRun if `openAPIConfig` is non-nil unless `skipOpenAPIInstallation` is true.
|
||||
OpenAPIVersionedService *handler.OpenAPIService
|
||||
|
||||
// OpenAPIV3VersionedService controls the /openapi/v3 endpoint and can be used to update the served spec.
|
||||
// It is set during PrepareRun if `openAPIConfig` is non-nil unless `skipOpenAPIInstallation` is true.
|
||||
OpenAPIV3VersionedService *handler3.OpenAPIService
|
||||
|
||||
// StaticOpenAPISpec is the spec derived from the restful container endpoints.
|
||||
// It is set during PrepareRun.
|
||||
StaticOpenAPISpec *spec.Swagger
|
||||
@@ -345,7 +350,12 @@ func (s *GenericAPIServer) PrepareRun() preparedGenericAPIServer {
|
||||
if s.openAPIConfig != nil && !s.skipOpenAPIInstallation {
|
||||
s.OpenAPIVersionedService, s.StaticOpenAPISpec = routes.OpenAPI{
|
||||
Config: s.openAPIConfig,
|
||||
}.Install(s.Handler.GoRestfulContainer, s.Handler.NonGoRestfulMux)
|
||||
}.InstallV2(s.Handler.GoRestfulContainer, s.Handler.NonGoRestfulMux)
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.OpenAPIV3) {
|
||||
s.OpenAPIV3VersionedService = routes.OpenAPI{
|
||||
Config: s.openAPIConfig,
|
||||
}.InstallV3(s.Handler.GoRestfulContainer, s.Handler.NonGoRestfulMux)
|
||||
}
|
||||
}
|
||||
|
||||
s.installHealthz()
|
||||
@@ -706,7 +716,7 @@ func (s *GenericAPIServer) getOpenAPIModels(apiPrefix string, apiGroupInfos ...*
|
||||
}
|
||||
|
||||
// Build the openapi definitions for those resources and convert it to proto models
|
||||
openAPISpec, err := openapibuilder.BuildOpenAPIDefinitionsForResources(s.openAPIConfig, resourceNames...)
|
||||
openAPISpec, err := openapibuilder2.BuildOpenAPIDefinitionsForResources(s.openAPIConfig, resourceNames...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -21,9 +21,11 @@ import (
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"k8s.io/apiserver/pkg/server/mux"
|
||||
"k8s.io/kube-openapi/pkg/builder"
|
||||
builder2 "k8s.io/kube-openapi/pkg/builder"
|
||||
"k8s.io/kube-openapi/pkg/builder3"
|
||||
"k8s.io/kube-openapi/pkg/common"
|
||||
"k8s.io/kube-openapi/pkg/handler"
|
||||
"k8s.io/kube-openapi/pkg/handler3"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
@@ -33,8 +35,8 @@ type OpenAPI struct {
|
||||
}
|
||||
|
||||
// Install adds the SwaggerUI webservice to the given mux.
|
||||
func (oa OpenAPI) Install(c *restful.Container, mux *mux.PathRecorderMux) (*handler.OpenAPIService, *spec.Swagger) {
|
||||
spec, err := builder.BuildOpenAPISpec(c.RegisteredWebServices(), oa.Config)
|
||||
func (oa OpenAPI) InstallV2(c *restful.Container, mux *mux.PathRecorderMux) (*handler.OpenAPIService, *spec.Swagger) {
|
||||
spec, err := builder2.BuildOpenAPISpec(c.RegisteredWebServices(), oa.Config)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to build open api spec for root: %v", err)
|
||||
}
|
||||
@@ -51,3 +53,34 @@ func (oa OpenAPI) Install(c *restful.Container, mux *mux.PathRecorderMux) (*hand
|
||||
|
||||
return openAPIVersionedService, spec
|
||||
}
|
||||
|
||||
// InstallV3 adds the static group/versions defined in the RegisteredWebServices to the OpenAPI v3 spec
|
||||
func (oa OpenAPI) InstallV3(c *restful.Container, mux *mux.PathRecorderMux) *handler3.OpenAPIService {
|
||||
openAPIVersionedService, err := handler3.NewOpenAPIService(nil)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to create OpenAPIService: %v", err)
|
||||
}
|
||||
|
||||
err = openAPIVersionedService.RegisterOpenAPIV3VersionedService("/openapi/v3", mux)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to register versioned open api spec for root: %v", err)
|
||||
}
|
||||
|
||||
grouped := make(map[string][]*restful.WebService)
|
||||
|
||||
for _, t := range c.RegisteredWebServices() {
|
||||
// Strip the "/" prefix from the name
|
||||
gvName := t.RootPath()[1:]
|
||||
grouped[gvName] = []*restful.WebService{t}
|
||||
}
|
||||
|
||||
for gv, ws := range grouped {
|
||||
spec, err := builder3.BuildOpenAPISpec(ws, oa.Config)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to build OpenAPI v3 for group %s, %q", gv, err)
|
||||
|
||||
}
|
||||
openAPIVersionedService.UpdateGroupVersion(gv, spec)
|
||||
}
|
||||
return openAPIVersionedService
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
genericfeatures "k8s.io/apiserver/pkg/features"
|
||||
genericapiserver "k8s.io/apiserver/pkg/server"
|
||||
"k8s.io/apiserver/pkg/server/egressselector"
|
||||
@@ -46,6 +47,8 @@ import (
|
||||
listers "k8s.io/kube-aggregator/pkg/client/listers/apiregistration/v1"
|
||||
openapicontroller "k8s.io/kube-aggregator/pkg/controllers/openapi"
|
||||
openapiaggregator "k8s.io/kube-aggregator/pkg/controllers/openapi/aggregator"
|
||||
openapiv3controller "k8s.io/kube-aggregator/pkg/controllers/openapiv3"
|
||||
openapiv3aggregator "k8s.io/kube-aggregator/pkg/controllers/openapiv3/aggregator"
|
||||
statuscontrollers "k8s.io/kube-aggregator/pkg/controllers/status"
|
||||
apiservicerest "k8s.io/kube-aggregator/pkg/registry/apiservice/rest"
|
||||
)
|
||||
@@ -141,9 +144,12 @@ type APIAggregator struct {
|
||||
// Enable swagger and/or OpenAPI if these configs are non-nil.
|
||||
openAPIConfig *openapicommon.Config
|
||||
|
||||
// openAPIAggregationController downloads and merges OpenAPI specs.
|
||||
// openAPIAggregationController downloads and merges OpenAPI v2 specs.
|
||||
openAPIAggregationController *openapicontroller.AggregationController
|
||||
|
||||
// openAPIV3AggregationController downloads and caches OpenAPI v3 specs.
|
||||
openAPIV3AggregationController *openapiv3controller.AggregationController
|
||||
|
||||
// egressSelector selects the proper egress dialer to communicate with the custom apiserver
|
||||
// overwrites proxyTransport dialer if not nil
|
||||
egressSelector *egressselector.EgressSelector
|
||||
@@ -344,6 +350,9 @@ func (s *APIAggregator) PrepareRun() (preparedAPIAggregator, error) {
|
||||
if s.openAPIConfig != nil {
|
||||
s.GenericAPIServer.AddPostStartHookOrDie("apiservice-openapi-controller", func(context genericapiserver.PostStartHookContext) error {
|
||||
go s.openAPIAggregationController.Run(context.StopCh)
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.OpenAPIV3) {
|
||||
go s.openAPIV3AggregationController.Run(context.StopCh)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -363,6 +372,18 @@ func (s *APIAggregator) PrepareRun() (preparedAPIAggregator, error) {
|
||||
return preparedAPIAggregator{}, err
|
||||
}
|
||||
s.openAPIAggregationController = openapicontroller.NewAggregationController(&specDownloader, openAPIAggregator)
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.OpenAPIV3) {
|
||||
specDownloaderV3 := openapiv3aggregator.NewDownloader()
|
||||
openAPIV3Aggregator, err := openapiv3aggregator.BuildAndRegisterAggregator(
|
||||
specDownloaderV3,
|
||||
s.GenericAPIServer.NextDelegate(),
|
||||
s.GenericAPIServer.Handler.NonGoRestfulMux)
|
||||
if err != nil {
|
||||
return preparedAPIAggregator{}, err
|
||||
}
|
||||
_ = openAPIV3Aggregator
|
||||
s.openAPIV3AggregationController = openapiv3controller.NewAggregationController(openAPIV3Aggregator)
|
||||
}
|
||||
}
|
||||
|
||||
return preparedAPIAggregator{APIAggregator: s, runnable: prepared}, nil
|
||||
@@ -382,6 +403,9 @@ func (s *APIAggregator) AddAPIService(apiService *v1.APIService) error {
|
||||
if s.openAPIAggregationController != nil {
|
||||
s.openAPIAggregationController.UpdateAPIService(proxyHandler, apiService)
|
||||
}
|
||||
if s.openAPIV3AggregationController != nil {
|
||||
s.openAPIV3AggregationController.UpdateAPIService(proxyHandler, apiService)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -403,6 +427,9 @@ func (s *APIAggregator) AddAPIService(apiService *v1.APIService) error {
|
||||
if s.openAPIAggregationController != nil {
|
||||
s.openAPIAggregationController.AddAPIService(proxyHandler, apiService)
|
||||
}
|
||||
if s.openAPIV3AggregationController != nil {
|
||||
s.openAPIV3AggregationController.AddAPIService(proxyHandler, apiService)
|
||||
}
|
||||
s.proxyHandlers[apiService.Name] = proxyHandler
|
||||
s.GenericAPIServer.Handler.NonGoRestfulMux.Handle(proxyPath, proxyHandler)
|
||||
s.GenericAPIServer.Handler.NonGoRestfulMux.UnlistedHandlePrefix(proxyPath+"/", proxyHandler)
|
||||
@@ -447,6 +474,9 @@ func (s *APIAggregator) RemoveAPIService(apiServiceName string) {
|
||||
if s.openAPIAggregationController != nil {
|
||||
s.openAPIAggregationController.RemoveAPIService(apiServiceName)
|
||||
}
|
||||
if s.openAPIV3AggregationController != nil {
|
||||
s.openAPIAggregationController.RemoveAPIService(apiServiceName)
|
||||
}
|
||||
delete(s.proxyHandlers, apiServiceName)
|
||||
|
||||
// TODO unregister group level discovery when there are no more versions for the group
|
||||
|
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package aggregator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"k8s.io/apiserver/pkg/server"
|
||||
v1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
|
||||
"k8s.io/kube-openapi/pkg/common"
|
||||
"k8s.io/kube-openapi/pkg/handler3"
|
||||
"k8s.io/kube-openapi/pkg/spec3"
|
||||
)
|
||||
|
||||
// SpecAggregator calls out to http handlers of APIServices and caches specs. It keeps state of the last
|
||||
// known specs including the http etag.
|
||||
// TODO(jefftree): remove the downloading and caching and proxy directly to the APIServices. This is possible because we
|
||||
// don't have to merge here, which is cpu intensive in v2
|
||||
type SpecAggregator interface {
|
||||
AddUpdateAPIService(handler http.Handler, apiService *v1.APIService)
|
||||
UpdateAPIServiceSpec(apiServiceName string) error
|
||||
RemoveAPIServiceSpec(apiServiceName string)
|
||||
GetAPIServiceNames() []string
|
||||
}
|
||||
|
||||
const (
|
||||
aggregatorUser = "system:aggregator"
|
||||
specDownloadTimeout = 60 * time.Second
|
||||
localDelegateChainNamePrefix = "k8s_internal_local_delegation_chain_"
|
||||
localDelegateChainNamePattern = localDelegateChainNamePrefix + "%010d"
|
||||
)
|
||||
|
||||
// IsLocalAPIService returns true for local specs from delegates.
|
||||
func IsLocalAPIService(apiServiceName string) bool {
|
||||
return strings.HasPrefix(apiServiceName, localDelegateChainNamePrefix)
|
||||
}
|
||||
|
||||
// GetAPIServicesName returns the names of APIServices recorded in openAPIV3Specs.
|
||||
// We use this function to pass the names of local APIServices to the controller in this package,
|
||||
// so that the controller can periodically sync the OpenAPI spec from delegation API servers.
|
||||
func (s *specAggregator) GetAPIServiceNames() []string {
|
||||
s.rwMutex.Lock()
|
||||
defer s.rwMutex.Unlock()
|
||||
|
||||
names := make([]string, len(s.openAPIV3Specs))
|
||||
for key := range s.openAPIV3Specs {
|
||||
names = append(names, key)
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// BuildAndRegisterAggregator registered OpenAPI aggregator handler. This function is not thread safe as it only being called on startup.
|
||||
func BuildAndRegisterAggregator(downloader Downloader, delegationTarget server.DelegationTarget, pathHandler common.PathHandlerByGroupVersion) (SpecAggregator, error) {
|
||||
var err error
|
||||
s := &specAggregator{
|
||||
openAPIV3Specs: map[string]*openAPIV3APIServiceInfo{},
|
||||
downloader: downloader,
|
||||
}
|
||||
|
||||
s.openAPIV3VersionedService, err = handler3.NewOpenAPIService(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = s.openAPIV3VersionedService.RegisterOpenAPIV3VersionedService("/openapi/v3", pathHandler)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
i := 1
|
||||
for delegate := delegationTarget; delegate != nil; delegate = delegate.NextDelegate() {
|
||||
handler := delegate.UnprotectedHandler()
|
||||
if handler == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
apiServiceName := fmt.Sprintf(localDelegateChainNamePattern, i)
|
||||
localAPIService := v1.APIService{}
|
||||
localAPIService.Name = apiServiceName
|
||||
s.AddUpdateAPIService(handler, &localAPIService)
|
||||
s.UpdateAPIServiceSpec(apiServiceName)
|
||||
i++
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// AddUpdateAPIService adds or updates the api service. It is thread safe.
|
||||
func (s *specAggregator) AddUpdateAPIService(handler http.Handler, apiservice *v1.APIService) {
|
||||
s.rwMutex.Lock()
|
||||
defer s.rwMutex.Unlock()
|
||||
// If the APIService is being updated, use the existing struct.
|
||||
if apiServiceInfo, ok := s.openAPIV3Specs[apiservice.Name]; ok {
|
||||
apiServiceInfo.apiService = *apiservice
|
||||
apiServiceInfo.handler = handler
|
||||
}
|
||||
s.openAPIV3Specs[apiservice.Name] = &openAPIV3APIServiceInfo{
|
||||
apiService: *apiservice,
|
||||
handler: handler,
|
||||
specs: make(map[string]*openAPIV3SpecInfo),
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateAPIServiceSpec updates all the OpenAPI v3 specs that the APIService serves.
|
||||
// It is thread safe.
|
||||
func (s *specAggregator) UpdateAPIServiceSpec(apiServiceName string) error {
|
||||
s.rwMutex.Lock()
|
||||
defer s.rwMutex.Unlock()
|
||||
|
||||
apiService, exists := s.openAPIV3Specs[apiServiceName]
|
||||
if !exists {
|
||||
return fmt.Errorf("APIService %s does not exist for update", apiServiceName)
|
||||
}
|
||||
|
||||
// Pass a list of old etags to the Downloader to prevent transfers if etags match
|
||||
etagList := make(map[string]string)
|
||||
for gv, specInfo := range apiService.specs {
|
||||
etagList[gv] = specInfo.etag
|
||||
}
|
||||
groups, err := s.downloader.Download(apiService.handler, etagList)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Remove any groups that do not exist anymore
|
||||
for group := range s.openAPIV3Specs[apiServiceName].specs {
|
||||
if _, exists := groups[group]; !exists {
|
||||
s.openAPIV3VersionedService.DeleteGroupVersion(group)
|
||||
delete(s.openAPIV3Specs[apiServiceName].specs, group)
|
||||
}
|
||||
}
|
||||
|
||||
for group, info := range groups {
|
||||
if info.spec == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// If ETag has not changed, no update is necessary
|
||||
oldInfo, exists := s.openAPIV3Specs[apiServiceName].specs[group]
|
||||
if exists && oldInfo.etag == info.etag {
|
||||
continue
|
||||
}
|
||||
s.openAPIV3Specs[apiServiceName].specs[group] = &openAPIV3SpecInfo{
|
||||
spec: info.spec,
|
||||
etag: info.etag,
|
||||
}
|
||||
s.openAPIV3VersionedService.UpdateGroupVersion(group, info.spec)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type specAggregator struct {
|
||||
// mutex protects all members of this struct.
|
||||
rwMutex sync.RWMutex
|
||||
|
||||
// OpenAPI V3 specs by APIService name
|
||||
openAPIV3Specs map[string]*openAPIV3APIServiceInfo
|
||||
// provided for dynamic OpenAPI spec
|
||||
openAPIV3VersionedService *handler3.OpenAPIService
|
||||
|
||||
// For downloading the OpenAPI v3 specs from apiservices
|
||||
downloader Downloader
|
||||
}
|
||||
|
||||
var _ SpecAggregator = &specAggregator{}
|
||||
|
||||
type openAPIV3APIServiceInfo struct {
|
||||
apiService v1.APIService
|
||||
handler http.Handler
|
||||
specs map[string]*openAPIV3SpecInfo
|
||||
}
|
||||
|
||||
type openAPIV3SpecInfo struct {
|
||||
spec *spec3.OpenAPI
|
||||
etag string
|
||||
}
|
||||
|
||||
// RemoveAPIServiceSpec removes an api service from the OpenAPI map. If it does not exist, no error is returned.
|
||||
// It is thread safe.
|
||||
func (s *specAggregator) RemoveAPIServiceSpec(apiServiceName string) {
|
||||
s.rwMutex.Lock()
|
||||
defer s.rwMutex.Unlock()
|
||||
if apiServiceInfo, ok := s.openAPIV3Specs[apiServiceName]; ok {
|
||||
for gv := range apiServiceInfo.specs {
|
||||
s.openAPIV3VersionedService.DeleteGroupVersion(gv)
|
||||
}
|
||||
delete(s.openAPIV3Specs, apiServiceName)
|
||||
}
|
||||
}
|
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package aggregator
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
"k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kube-openapi/pkg/spec3"
|
||||
)
|
||||
|
||||
// Downloader is the OpenAPI downloader type. It will try to download spec from /openapi/v3 and /openap/v3/<group>/<version> endpoints.
|
||||
type Downloader struct {
|
||||
}
|
||||
|
||||
// NewDownloader creates a new OpenAPI Downloader.
|
||||
func NewDownloader() Downloader {
|
||||
return Downloader{}
|
||||
}
|
||||
|
||||
func (s *Downloader) handlerWithUser(handler http.Handler, info user.Info) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
req = req.WithContext(request.WithUser(req.Context(), info))
|
||||
handler.ServeHTTP(w, req)
|
||||
})
|
||||
}
|
||||
|
||||
// gvList is a struct for the response of the /openapi/v3 endpoint to unmarshal into
|
||||
type gvList struct {
|
||||
Paths []string `json:"Paths"`
|
||||
}
|
||||
|
||||
// SpecETag is a OpenAPI v3 spec and etag pair for the endpoint of each OpenAPI group/version
|
||||
type SpecETag struct {
|
||||
spec *spec3.OpenAPI
|
||||
etag string
|
||||
}
|
||||
|
||||
// Download downloads OpenAPI v3 for all groups of a given handler
|
||||
func (s *Downloader) Download(handler http.Handler, etagList map[string]string) (returnSpec map[string]*SpecETag, err error) {
|
||||
// TODO(jefftree): https://github.com/kubernetes/kubernetes/pull/105945#issuecomment-966455034
|
||||
// Move to proxy request in the aggregator and let the APIServices serve the OpenAPI directly
|
||||
handler = s.handlerWithUser(handler, &user.DefaultInfo{Name: aggregatorUser})
|
||||
handler = http.TimeoutHandler(handler, specDownloadTimeout, "request timed out")
|
||||
|
||||
req, err := http.NewRequest("GET", "/openapi/v3", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Add("Accept", "application/json")
|
||||
|
||||
writer := newInMemoryResponseWriter()
|
||||
handler.ServeHTTP(writer, req)
|
||||
|
||||
switch writer.respCode {
|
||||
case http.StatusNotFound:
|
||||
// Gracefully skip 404, assuming the server won't provide any spec
|
||||
return nil, nil
|
||||
case http.StatusOK:
|
||||
groups := gvList{}
|
||||
aggregated := make(map[string]*SpecETag)
|
||||
|
||||
if err := json.Unmarshal(writer.data, &groups); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, path := range groups.Paths {
|
||||
reqPath := fmt.Sprintf("/openapi/v3/%s", path)
|
||||
req, err := http.NewRequest("GET", reqPath, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Add("Accept", "application/json")
|
||||
oldEtag, ok := etagList[path]
|
||||
if ok {
|
||||
req.Header.Add("If-None-Match", oldEtag)
|
||||
}
|
||||
openAPIWriter := newInMemoryResponseWriter()
|
||||
handler.ServeHTTP(openAPIWriter, req)
|
||||
|
||||
switch openAPIWriter.respCode {
|
||||
case http.StatusNotFound:
|
||||
continue
|
||||
case http.StatusNotModified:
|
||||
aggregated[path] = &SpecETag{
|
||||
etag: oldEtag,
|
||||
}
|
||||
case http.StatusOK:
|
||||
var spec spec3.OpenAPI
|
||||
// TODO|jefftree: For OpenAPI v3 Beta, if the v3 spec is empty then
|
||||
// we should request the v2 endpoint and convert it to v3
|
||||
if len(openAPIWriter.data) > 0 {
|
||||
err = json.Unmarshal(openAPIWriter.data, &spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
etag := openAPIWriter.Header().Get("Etag")
|
||||
aggregated[path] = &SpecETag{
|
||||
spec: &spec,
|
||||
etag: etag,
|
||||
}
|
||||
}
|
||||
default:
|
||||
klog.Errorf("Error: unknown status %v", openAPIWriter.respCode)
|
||||
}
|
||||
}
|
||||
|
||||
return aggregated, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("failed to retrieve openAPI spec, http error: %s", writer.String())
|
||||
}
|
||||
}
|
||||
|
||||
// inMemoryResponseWriter is a http.Writer that keep the response in memory.
|
||||
type inMemoryResponseWriter struct {
|
||||
writeHeaderCalled bool
|
||||
header http.Header
|
||||
respCode int
|
||||
data []byte
|
||||
}
|
||||
|
||||
func newInMemoryResponseWriter() *inMemoryResponseWriter {
|
||||
return &inMemoryResponseWriter{header: http.Header{}}
|
||||
}
|
||||
|
||||
func (r *inMemoryResponseWriter) Header() http.Header {
|
||||
return r.header
|
||||
}
|
||||
|
||||
func (r *inMemoryResponseWriter) WriteHeader(code int) {
|
||||
r.writeHeaderCalled = true
|
||||
r.respCode = code
|
||||
}
|
||||
|
||||
func (r *inMemoryResponseWriter) Write(in []byte) (int, error) {
|
||||
if !r.writeHeaderCalled {
|
||||
r.WriteHeader(http.StatusOK)
|
||||
}
|
||||
r.data = append(r.data, in...)
|
||||
return len(in), nil
|
||||
}
|
||||
|
||||
func (r *inMemoryResponseWriter) String() string {
|
||||
s := fmt.Sprintf("ResponseCode: %d", r.respCode)
|
||||
if r.data != nil {
|
||||
s += fmt.Sprintf(", Body: %s", string(r.data))
|
||||
}
|
||||
if r.header != nil {
|
||||
s += fmt.Sprintf(", Header: %s", r.header)
|
||||
}
|
||||
return s
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package aggregator
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type handlerTest struct {
|
||||
etag string
|
||||
data []byte
|
||||
}
|
||||
|
||||
var _ http.Handler = handlerTest{}
|
||||
|
||||
func (h handlerTest) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// Create an APIService with a handler for one group/version
|
||||
group := make(map[string][]string)
|
||||
group["Paths"] = []string{"apis/group/version"}
|
||||
j, _ := json.Marshal(group)
|
||||
if r.URL.Path == "/openapi/v3" {
|
||||
w.Write(j)
|
||||
return
|
||||
}
|
||||
|
||||
if r.URL.Path == "/openapi/v3/apis/group/version" {
|
||||
if len(h.etag) > 0 {
|
||||
w.Header().Add("Etag", h.etag)
|
||||
}
|
||||
ifNoneMatches := r.Header["If-None-Match"]
|
||||
for _, match := range ifNoneMatches {
|
||||
if match == h.etag {
|
||||
w.WriteHeader(http.StatusNotModified)
|
||||
return
|
||||
}
|
||||
}
|
||||
w.Write(h.data)
|
||||
}
|
||||
}
|
||||
|
||||
func assertDownloadedSpec(gvSpec map[string]*SpecETag, err error, expectedSpecID string, expectedEtag string) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("downloadOpenAPISpec failed : %s", err)
|
||||
}
|
||||
specInfo, ok := gvSpec["apis/group/version"]
|
||||
if !ok {
|
||||
if expectedSpecID == "" {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("expected to download spec, no spec downloaded")
|
||||
}
|
||||
|
||||
if specInfo.spec != nil && expectedSpecID == "" {
|
||||
return fmt.Errorf("expected ID %s, actual ID %s", expectedSpecID, specInfo.spec.Version)
|
||||
}
|
||||
|
||||
if specInfo.spec != nil && specInfo.spec.Version != expectedSpecID {
|
||||
return fmt.Errorf("expected ID %s, actual ID %s", expectedSpecID, specInfo.spec.Version)
|
||||
}
|
||||
if specInfo.etag != expectedEtag {
|
||||
return fmt.Errorf("expected ETag '%s', actual ETag '%s'", expectedEtag, specInfo.etag)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestDownloadOpenAPISpec(t *testing.T) {
|
||||
s := Downloader{}
|
||||
|
||||
// Test with eTag
|
||||
gvSpec, err := s.Download(
|
||||
handlerTest{data: []byte("{\"openapi\": \"test\"}"), etag: "etag_test"}, map[string]string{})
|
||||
assert.NoError(t, assertDownloadedSpec(gvSpec, err, "test", "etag_test"))
|
||||
|
||||
// Test not modified
|
||||
gvSpec, err = s.Download(
|
||||
handlerTest{data: []byte("{\"openapi\": \"test\"}"), etag: "etag_test"}, map[string]string{"apis/group/version": "etag_test"})
|
||||
assert.NoError(t, assertDownloadedSpec(gvSpec, err, "", "etag_test"))
|
||||
|
||||
// Test different eTags
|
||||
gvSpec, err = s.Download(
|
||||
handlerTest{data: []byte("{\"openapi\": \"test\"}"), etag: "etag_test1"}, map[string]string{"apis/group/version": "etag_test2"})
|
||||
assert.NoError(t, assertDownloadedSpec(gvSpec, err, "test", "etag_test1"))
|
||||
}
|
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package openapiv3
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
|
||||
"k8s.io/kube-aggregator/pkg/controllers/openapiv3/aggregator"
|
||||
)
|
||||
|
||||
const (
|
||||
successfulUpdateDelay = time.Minute
|
||||
successfulUpdateDelayLocal = time.Second
|
||||
failedUpdateMaxExpDelay = time.Hour
|
||||
)
|
||||
|
||||
type syncAction int
|
||||
|
||||
const (
|
||||
syncRequeue syncAction = iota
|
||||
syncRequeueRateLimited
|
||||
syncNothing
|
||||
)
|
||||
|
||||
// AggregationController periodically check for changes in OpenAPI specs of APIServices and update/remove
|
||||
// them if necessary.
|
||||
type AggregationController struct {
|
||||
openAPIAggregationManager aggregator.SpecAggregator
|
||||
queue workqueue.RateLimitingInterface
|
||||
|
||||
// To allow injection for testing.
|
||||
syncHandler func(key string) (syncAction, error)
|
||||
}
|
||||
|
||||
// NewAggregationController creates new OpenAPI aggregation controller.
|
||||
func NewAggregationController(openAPIAggregationManager aggregator.SpecAggregator) *AggregationController {
|
||||
c := &AggregationController{
|
||||
openAPIAggregationManager: openAPIAggregationManager,
|
||||
queue: workqueue.NewNamedRateLimitingQueue(
|
||||
workqueue.NewItemExponentialFailureRateLimiter(successfulUpdateDelay, failedUpdateMaxExpDelay),
|
||||
"open_api_v3_aggregation_controller",
|
||||
),
|
||||
}
|
||||
|
||||
c.syncHandler = c.sync
|
||||
|
||||
// update each service at least once, also those which are not coming from APIServices, namely local services
|
||||
for _, name := range openAPIAggregationManager.GetAPIServiceNames() {
|
||||
c.queue.AddAfter(name, time.Second)
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// Run starts OpenAPI AggregationController
|
||||
func (c *AggregationController) Run(stopCh <-chan struct{}) {
|
||||
defer utilruntime.HandleCrash()
|
||||
defer c.queue.ShutDown()
|
||||
|
||||
klog.Info("Starting OpenAPI V3 AggregationController")
|
||||
defer klog.Info("Shutting down OpenAPI V3 AggregationController")
|
||||
|
||||
go wait.Until(c.runWorker, time.Second, stopCh)
|
||||
|
||||
<-stopCh
|
||||
}
|
||||
|
||||
func (c *AggregationController) runWorker() {
|
||||
for c.processNextWorkItem() {
|
||||
}
|
||||
}
|
||||
|
||||
// processNextWorkItem deals with one key off the queue. It returns false when it's time to quit.
|
||||
func (c *AggregationController) processNextWorkItem() bool {
|
||||
key, quit := c.queue.Get()
|
||||
defer c.queue.Done(key)
|
||||
if quit {
|
||||
return false
|
||||
}
|
||||
|
||||
if aggregator.IsLocalAPIService(key.(string)) {
|
||||
// for local delegation targets that are aggregated once per second, log at
|
||||
// higher level to avoid flooding the log
|
||||
klog.V(6).Infof("OpenAPI AggregationController: Processing item %s", key)
|
||||
} else {
|
||||
klog.V(4).Infof("OpenAPI AggregationController: Processing item %s", key)
|
||||
}
|
||||
|
||||
action, err := c.syncHandler(key.(string))
|
||||
if err == nil {
|
||||
c.queue.Forget(key)
|
||||
} else {
|
||||
utilruntime.HandleError(fmt.Errorf("loading OpenAPI spec for %q failed with: %v", key, err))
|
||||
}
|
||||
|
||||
switch action {
|
||||
case syncRequeue:
|
||||
if aggregator.IsLocalAPIService(key.(string)) {
|
||||
klog.V(7).Infof("OpenAPI AggregationController: action for local item %s: Requeue after %s.", key, successfulUpdateDelayLocal)
|
||||
c.queue.AddAfter(key, successfulUpdateDelayLocal)
|
||||
} else {
|
||||
klog.V(7).Infof("OpenAPI AggregationController: action for item %s: Requeue.", key)
|
||||
c.queue.AddAfter(key, successfulUpdateDelay)
|
||||
}
|
||||
case syncRequeueRateLimited:
|
||||
klog.Infof("OpenAPI AggregationController: action for item %s: Rate Limited Requeue.", key)
|
||||
c.queue.AddRateLimited(key)
|
||||
case syncNothing:
|
||||
klog.Infof("OpenAPI AggregationController: action for item %s: Nothing (removed from the queue).", key)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *AggregationController) sync(key string) (syncAction, error) {
|
||||
err := c.openAPIAggregationManager.UpdateAPIServiceSpec(key)
|
||||
switch {
|
||||
case err != nil:
|
||||
return syncRequeueRateLimited, err
|
||||
}
|
||||
return syncRequeue, nil
|
||||
}
|
||||
|
||||
// AddAPIService adds a new API Service to OpenAPI Aggregation.
|
||||
func (c *AggregationController) AddAPIService(handler http.Handler, apiService *v1.APIService) {
|
||||
if apiService.Spec.Service == nil {
|
||||
return
|
||||
}
|
||||
c.openAPIAggregationManager.AddUpdateAPIService(handler, apiService)
|
||||
c.queue.AddAfter(apiService.Name, time.Second)
|
||||
}
|
||||
|
||||
// UpdateAPIService updates API Service's info and handler.
|
||||
func (c *AggregationController) UpdateAPIService(handler http.Handler, apiService *v1.APIService) {
|
||||
if apiService.Spec.Service == nil {
|
||||
return
|
||||
}
|
||||
c.openAPIAggregationManager.AddUpdateAPIService(handler, apiService)
|
||||
key := apiService.Name
|
||||
if c.queue.NumRequeues(key) > 0 {
|
||||
// The item has failed before. Remove it from failure queue and
|
||||
// update it in a second
|
||||
c.queue.Forget(key)
|
||||
c.queue.AddAfter(key, time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveAPIService removes API Service from OpenAPI Aggregation Controller.
|
||||
func (c *AggregationController) RemoveAPIService(apiServiceName string) {
|
||||
c.openAPIAggregationManager.RemoveAPIServiceSpec(apiServiceName)
|
||||
// This will only remove it if it was failing before. If it was successful, processNextWorkItem will figure it out
|
||||
// and will not add it again to the queue.
|
||||
c.queue.Forget(apiServiceName)
|
||||
}
|
267
test/integration/apiserver/openapiv3_test.go
Normal file
267
test/integration/apiserver/openapiv3_test.go
Normal file
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package apiserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
openapi_v3 "github.com/googleapis/gnostic/openapiv3"
|
||||
"google.golang.org/protobuf/proto"
|
||||
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
"k8s.io/apiextensions-apiserver/test/integration/fixtures"
|
||||
genericfeatures "k8s.io/apiserver/pkg/features"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/client-go/dynamic"
|
||||
kubernetes "k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
"k8s.io/kube-openapi/pkg/spec3"
|
||||
apiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
|
||||
"k8s.io/kubernetes/test/integration/framework"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
func TestOpenAPIV3SpecRoundTrip(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.OpenAPIV3, true)()
|
||||
controlPlaneConfig := framework.NewIntegrationTestControlPlaneConfigWithOptions(&framework.ControlPlaneConfigOptions{})
|
||||
controlPlaneConfig.GenericConfig.OpenAPIConfig = framework.DefaultOpenAPIConfig()
|
||||
instanceConfig, _, closeFn := framework.RunAnAPIServer(controlPlaneConfig)
|
||||
defer closeFn()
|
||||
paths := []string{
|
||||
"/apis/apps/v1",
|
||||
"/apis/authentication.k8s.io/v1",
|
||||
"/apis/policy/v1",
|
||||
"/apis/batch/v1",
|
||||
"/version",
|
||||
}
|
||||
for _, path := range paths {
|
||||
t.Run(path, func(t *testing.T) {
|
||||
rt, err := restclient.TransportFor(instanceConfig.GenericAPIServer.LoopbackClientConfig)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// attempt to fetch and unmarshal
|
||||
url := instanceConfig.GenericAPIServer.LoopbackClientConfig.Host + "/openapi/v3" + path
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
resp, err := rt.RoundTrip(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
bs, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var firstSpec spec3.OpenAPI
|
||||
err = json.Unmarshal(bs, &firstSpec)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
specBytes, err := json.Marshal(&firstSpec)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var secondSpec spec3.OpenAPI
|
||||
err = json.Unmarshal(specBytes, &secondSpec)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(firstSpec, secondSpec) {
|
||||
t.Fatal("spec mismatch")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddRemoveGroupVersion(t *testing.T) {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.OpenAPIV3, true)()
|
||||
server, err := apiservertesting.StartTestServer(t, apiservertesting.NewDefaultTestServerOptions(), nil, framework.SharedEtcd())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer server.TearDownFn()
|
||||
config := server.ClientConfig
|
||||
|
||||
apiExtensionClient, err := clientset.NewForConfig(config)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
dynamicClient, err := dynamic.NewForConfig(config)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
clientset, err := kubernetes.NewForConfig(config)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Create a new CRD with group mygroup.example.com
|
||||
noxuDefinition := fixtures.NewNoxuV1CustomResourceDefinition(apiextensionsv1.NamespaceScoped)
|
||||
noxuDefinition, err = fixtures.CreateNewV1CustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// It takes a second for CRD specs to propagate to the aggregator
|
||||
time.Sleep(4 * time.Second)
|
||||
|
||||
// Verify that the new group version is populated in the discovery for OpenaPI v3
|
||||
jsonData, err := clientset.RESTClient().Get().AbsPath("/openapi/v3").Do(context.TODO()).Raw()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
openAPIv3GV := make(map[string][]string)
|
||||
err = json.Unmarshal(jsonData, &openAPIv3GV)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
paths, ok := openAPIv3GV["Paths"]
|
||||
if !ok {
|
||||
t.Fatal("OpenAPI v3 format error")
|
||||
}
|
||||
|
||||
foundPath := false
|
||||
for _, path := range paths {
|
||||
if strings.Contains(path, "mygroup.example.com/v1beta1") {
|
||||
foundPath = true
|
||||
}
|
||||
}
|
||||
if foundPath == false {
|
||||
t.Fatal("Expected group version mygroup.example.com to be present after CRD applied")
|
||||
}
|
||||
|
||||
// Check the spec for the newly published group version
|
||||
jsonData, err = clientset.RESTClient().Get().AbsPath("/openapi/v3/apis/mygroup.example.com/v1beta1").Do(context.TODO()).Raw()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var firstSpec spec3.OpenAPI
|
||||
err = json.Unmarshal(jsonData, &firstSpec)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Delete the CRD and ensure that the group/version is also deleted in discovery
|
||||
if err := fixtures.DeleteV1CustomResourceDefinition(noxuDefinition, apiExtensionClient); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
time.Sleep(4 * time.Second)
|
||||
|
||||
jsonData, err = clientset.RESTClient().Get().AbsPath("/openapi/v3").Do(context.TODO()).Raw()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = json.Unmarshal(jsonData, &openAPIv3GV)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
paths, ok = openAPIv3GV["Paths"]
|
||||
if !ok {
|
||||
t.Fatal("OpenAPI v3 format error")
|
||||
}
|
||||
|
||||
for _, path := range paths {
|
||||
if strings.Contains(path, "mygroup.example.com") {
|
||||
t.Fatal("Unexpected group version mygroup.example.com in OpenAPI v3 discovery")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenAPIV3ProtoRoundtrip(t *testing.T) {
|
||||
// The OpenAPI V3 proto library strips fields that are sibling elements to $ref
|
||||
// See https://github.com/kubernetes/kubernetes/issues/106387 for more details
|
||||
t.Skip("Skipping OpenAPI V3 Proto roundtrip test")
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, genericfeatures.OpenAPIV3, true)()
|
||||
controlPlaneConfig := framework.NewIntegrationTestControlPlaneConfigWithOptions(&framework.ControlPlaneConfigOptions{})
|
||||
controlPlaneConfig.GenericConfig.OpenAPIConfig = framework.DefaultOpenAPIConfig()
|
||||
instanceConfig, _, closeFn := framework.RunAnAPIServer(controlPlaneConfig)
|
||||
defer closeFn()
|
||||
rt, err := restclient.TransportFor(instanceConfig.GenericAPIServer.LoopbackClientConfig)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// attempt to fetch and unmarshal
|
||||
req, err := http.NewRequest("GET", instanceConfig.GenericAPIServer.LoopbackClientConfig.Host+"/openapi/v3/apis/apps/v1", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
resp, err := rt.RoundTrip(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
bs, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var firstSpec spec3.OpenAPI
|
||||
err = json.Unmarshal(bs, &firstSpec)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
protoReq, err := http.NewRequest("GET", instanceConfig.GenericAPIServer.LoopbackClientConfig.Host+"/openapi/v3/apis/apps/v1", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
protoReq.Header.Set("Accept", "application/com.github.proto-openapi.spec.v3@v1.0+protobuf")
|
||||
protoResp, err := rt.RoundTrip(protoReq)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer protoResp.Body.Close()
|
||||
bs, err = ioutil.ReadAll(protoResp.Body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var protoDoc openapi_v3.Document
|
||||
err = proto.Unmarshal(bs, &protoDoc)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
yamlBytes, err := protoDoc.YAMLValue("")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
jsonBytes, err := yaml.YAMLToJSON(yamlBytes)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var specFromProto spec3.OpenAPI
|
||||
err = json.Unmarshal(jsonBytes, &specFromProto)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(specFromProto, firstSpec) {
|
||||
t.Fatalf("spec mismatch - specFromProto: %s\n", jsonBytes)
|
||||
}
|
||||
}
|
8598
vendor/github.com/googleapis/gnostic/openapiv3/OpenAPIv3.go
generated
vendored
Normal file
8598
vendor/github.com/googleapis/gnostic/openapiv3/OpenAPIv3.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8033
vendor/github.com/googleapis/gnostic/openapiv3/OpenAPIv3.pb.go
generated
vendored
Normal file
8033
vendor/github.com/googleapis/gnostic/openapiv3/OpenAPIv3.pb.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
670
vendor/github.com/googleapis/gnostic/openapiv3/OpenAPIv3.proto
generated
vendored
Normal file
670
vendor/github.com/googleapis/gnostic/openapiv3/OpenAPIv3.proto
generated
vendored
Normal file
@@ -0,0 +1,670 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package openapi.v3;
|
||||
|
||||
import "google/protobuf/any.proto";
|
||||
|
||||
// This option lets the proto compiler generate Java code inside the package
|
||||
// name (see below) instead of inside an outer class. It creates a simpler
|
||||
// developer experience by reducing one-level of name nesting and be
|
||||
// consistent with most programming languages that don't support outer classes.
|
||||
option java_multiple_files = true;
|
||||
|
||||
// The Java outer classname should be the filename in UpperCamelCase. This
|
||||
// class is only used to hold proto descriptor, so developers don't need to
|
||||
// work with it directly.
|
||||
option java_outer_classname = "OpenAPIProto";
|
||||
|
||||
// The Java package name must be proto package name with proper prefix.
|
||||
option java_package = "org.openapi_v3";
|
||||
|
||||
// A reasonable prefix for the Objective-C symbols generated from the package.
|
||||
// It should at a minimum be 3 characters long, all uppercase, and convention
|
||||
// is to use an abbreviation of the package name. Something short, but
|
||||
// hopefully unique enough to not conflict with things that may come along in
|
||||
// the future. 'GPB' is reserved for the protocol buffer implementation itself.
|
||||
option objc_class_prefix = "OAS";
|
||||
|
||||
// The Go package name.
|
||||
option go_package = "./openapiv3;openapi_v3";
|
||||
|
||||
message AdditionalPropertiesItem {
|
||||
oneof oneof {
|
||||
SchemaOrReference schema_or_reference = 1;
|
||||
bool boolean = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message Any {
|
||||
google.protobuf.Any value = 1;
|
||||
string yaml = 2;
|
||||
}
|
||||
|
||||
message AnyOrExpression {
|
||||
oneof oneof {
|
||||
Any any = 1;
|
||||
Expression expression = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// A map of possible out-of band callbacks related to the parent operation. Each value in the map is a Path Item Object that describes a set of requests that may be initiated by the API provider and the expected responses. The key value used to identify the callback object is an expression, evaluated at runtime, that identifies a URL to use for the callback operation.
|
||||
message Callback {
|
||||
repeated NamedPathItem path = 1;
|
||||
repeated NamedAny specification_extension = 2;
|
||||
}
|
||||
|
||||
message CallbackOrReference {
|
||||
oneof oneof {
|
||||
Callback callback = 1;
|
||||
Reference reference = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message CallbacksOrReferences {
|
||||
repeated NamedCallbackOrReference additional_properties = 1;
|
||||
}
|
||||
|
||||
// Holds a set of reusable objects for different aspects of the OAS. All objects defined within the components object will have no effect on the API unless they are explicitly referenced from properties outside the components object.
|
||||
message Components {
|
||||
SchemasOrReferences schemas = 1;
|
||||
ResponsesOrReferences responses = 2;
|
||||
ParametersOrReferences parameters = 3;
|
||||
ExamplesOrReferences examples = 4;
|
||||
RequestBodiesOrReferences request_bodies = 5;
|
||||
HeadersOrReferences headers = 6;
|
||||
SecuritySchemesOrReferences security_schemes = 7;
|
||||
LinksOrReferences links = 8;
|
||||
CallbacksOrReferences callbacks = 9;
|
||||
repeated NamedAny specification_extension = 10;
|
||||
}
|
||||
|
||||
// Contact information for the exposed API.
|
||||
message Contact {
|
||||
string name = 1;
|
||||
string url = 2;
|
||||
string email = 3;
|
||||
repeated NamedAny specification_extension = 4;
|
||||
}
|
||||
|
||||
message DefaultType {
|
||||
oneof oneof {
|
||||
double number = 1;
|
||||
bool boolean = 2;
|
||||
string string = 3;
|
||||
}
|
||||
}
|
||||
|
||||
// When request bodies or response payloads may be one of a number of different schemas, a `discriminator` object can be used to aid in serialization, deserialization, and validation. The discriminator is a specific object in a schema which is used to inform the consumer of the specification of an alternative schema based on the value associated with it. When using the discriminator, _inline_ schemas will not be considered.
|
||||
message Discriminator {
|
||||
string property_name = 1;
|
||||
Strings mapping = 2;
|
||||
repeated NamedAny specification_extension = 3;
|
||||
}
|
||||
|
||||
message Document {
|
||||
string openapi = 1;
|
||||
Info info = 2;
|
||||
repeated Server servers = 3;
|
||||
Paths paths = 4;
|
||||
Components components = 5;
|
||||
repeated SecurityRequirement security = 6;
|
||||
repeated Tag tags = 7;
|
||||
ExternalDocs external_docs = 8;
|
||||
repeated NamedAny specification_extension = 9;
|
||||
}
|
||||
|
||||
// A single encoding definition applied to a single schema property.
|
||||
message Encoding {
|
||||
string content_type = 1;
|
||||
HeadersOrReferences headers = 2;
|
||||
string style = 3;
|
||||
bool explode = 4;
|
||||
bool allow_reserved = 5;
|
||||
repeated NamedAny specification_extension = 6;
|
||||
}
|
||||
|
||||
message Encodings {
|
||||
repeated NamedEncoding additional_properties = 1;
|
||||
}
|
||||
|
||||
message Example {
|
||||
string summary = 1;
|
||||
string description = 2;
|
||||
Any value = 3;
|
||||
string external_value = 4;
|
||||
repeated NamedAny specification_extension = 5;
|
||||
}
|
||||
|
||||
message ExampleOrReference {
|
||||
oneof oneof {
|
||||
Example example = 1;
|
||||
Reference reference = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message ExamplesOrReferences {
|
||||
repeated NamedExampleOrReference additional_properties = 1;
|
||||
}
|
||||
|
||||
message Expression {
|
||||
repeated NamedAny additional_properties = 1;
|
||||
}
|
||||
|
||||
// Allows referencing an external resource for extended documentation.
|
||||
message ExternalDocs {
|
||||
string description = 1;
|
||||
string url = 2;
|
||||
repeated NamedAny specification_extension = 3;
|
||||
}
|
||||
|
||||
// The Header Object follows the structure of the Parameter Object with the following changes: 1. `name` MUST NOT be specified, it is given in the corresponding `headers` map. 1. `in` MUST NOT be specified, it is implicitly in `header`. 1. All traits that are affected by the location MUST be applicable to a location of `header` (for example, `style`).
|
||||
message Header {
|
||||
string description = 1;
|
||||
bool required = 2;
|
||||
bool deprecated = 3;
|
||||
bool allow_empty_value = 4;
|
||||
string style = 5;
|
||||
bool explode = 6;
|
||||
bool allow_reserved = 7;
|
||||
SchemaOrReference schema = 8;
|
||||
Any example = 9;
|
||||
ExamplesOrReferences examples = 10;
|
||||
MediaTypes content = 11;
|
||||
repeated NamedAny specification_extension = 12;
|
||||
}
|
||||
|
||||
message HeaderOrReference {
|
||||
oneof oneof {
|
||||
Header header = 1;
|
||||
Reference reference = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message HeadersOrReferences {
|
||||
repeated NamedHeaderOrReference additional_properties = 1;
|
||||
}
|
||||
|
||||
// The object provides metadata about the API. The metadata MAY be used by the clients if needed, and MAY be presented in editing or documentation generation tools for convenience.
|
||||
message Info {
|
||||
string title = 1;
|
||||
string description = 2;
|
||||
string terms_of_service = 3;
|
||||
Contact contact = 4;
|
||||
License license = 5;
|
||||
string version = 6;
|
||||
repeated NamedAny specification_extension = 7;
|
||||
string summary = 8;
|
||||
}
|
||||
|
||||
message ItemsItem {
|
||||
repeated SchemaOrReference schema_or_reference = 1;
|
||||
}
|
||||
|
||||
// License information for the exposed API.
|
||||
message License {
|
||||
string name = 1;
|
||||
string url = 2;
|
||||
repeated NamedAny specification_extension = 3;
|
||||
}
|
||||
|
||||
// The `Link object` represents a possible design-time link for a response. The presence of a link does not guarantee the caller's ability to successfully invoke it, rather it provides a known relationship and traversal mechanism between responses and other operations. Unlike _dynamic_ links (i.e. links provided **in** the response payload), the OAS linking mechanism does not require link information in the runtime response. For computing links, and providing instructions to execute them, a runtime expression is used for accessing values in an operation and using them as parameters while invoking the linked operation.
|
||||
message Link {
|
||||
string operation_ref = 1;
|
||||
string operation_id = 2;
|
||||
AnyOrExpression parameters = 3;
|
||||
AnyOrExpression request_body = 4;
|
||||
string description = 5;
|
||||
Server server = 6;
|
||||
repeated NamedAny specification_extension = 7;
|
||||
}
|
||||
|
||||
message LinkOrReference {
|
||||
oneof oneof {
|
||||
Link link = 1;
|
||||
Reference reference = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message LinksOrReferences {
|
||||
repeated NamedLinkOrReference additional_properties = 1;
|
||||
}
|
||||
|
||||
// Each Media Type Object provides schema and examples for the media type identified by its key.
|
||||
message MediaType {
|
||||
SchemaOrReference schema = 1;
|
||||
Any example = 2;
|
||||
ExamplesOrReferences examples = 3;
|
||||
Encodings encoding = 4;
|
||||
repeated NamedAny specification_extension = 5;
|
||||
}
|
||||
|
||||
message MediaTypes {
|
||||
repeated NamedMediaType additional_properties = 1;
|
||||
}
|
||||
|
||||
// Automatically-generated message used to represent maps of Any as ordered (name,value) pairs.
|
||||
message NamedAny {
|
||||
// Map key
|
||||
string name = 1;
|
||||
// Mapped value
|
||||
Any value = 2;
|
||||
}
|
||||
|
||||
// Automatically-generated message used to represent maps of CallbackOrReference as ordered (name,value) pairs.
|
||||
message NamedCallbackOrReference {
|
||||
// Map key
|
||||
string name = 1;
|
||||
// Mapped value
|
||||
CallbackOrReference value = 2;
|
||||
}
|
||||
|
||||
// Automatically-generated message used to represent maps of Encoding as ordered (name,value) pairs.
|
||||
message NamedEncoding {
|
||||
// Map key
|
||||
string name = 1;
|
||||
// Mapped value
|
||||
Encoding value = 2;
|
||||
}
|
||||
|
||||
// Automatically-generated message used to represent maps of ExampleOrReference as ordered (name,value) pairs.
|
||||
message NamedExampleOrReference {
|
||||
// Map key
|
||||
string name = 1;
|
||||
// Mapped value
|
||||
ExampleOrReference value = 2;
|
||||
}
|
||||
|
||||
// Automatically-generated message used to represent maps of HeaderOrReference as ordered (name,value) pairs.
|
||||
message NamedHeaderOrReference {
|
||||
// Map key
|
||||
string name = 1;
|
||||
// Mapped value
|
||||
HeaderOrReference value = 2;
|
||||
}
|
||||
|
||||
// Automatically-generated message used to represent maps of LinkOrReference as ordered (name,value) pairs.
|
||||
message NamedLinkOrReference {
|
||||
// Map key
|
||||
string name = 1;
|
||||
// Mapped value
|
||||
LinkOrReference value = 2;
|
||||
}
|
||||
|
||||
// Automatically-generated message used to represent maps of MediaType as ordered (name,value) pairs.
|
||||
message NamedMediaType {
|
||||
// Map key
|
||||
string name = 1;
|
||||
// Mapped value
|
||||
MediaType value = 2;
|
||||
}
|
||||
|
||||
// Automatically-generated message used to represent maps of ParameterOrReference as ordered (name,value) pairs.
|
||||
message NamedParameterOrReference {
|
||||
// Map key
|
||||
string name = 1;
|
||||
// Mapped value
|
||||
ParameterOrReference value = 2;
|
||||
}
|
||||
|
||||
// Automatically-generated message used to represent maps of PathItem as ordered (name,value) pairs.
|
||||
message NamedPathItem {
|
||||
// Map key
|
||||
string name = 1;
|
||||
// Mapped value
|
||||
PathItem value = 2;
|
||||
}
|
||||
|
||||
// Automatically-generated message used to represent maps of RequestBodyOrReference as ordered (name,value) pairs.
|
||||
message NamedRequestBodyOrReference {
|
||||
// Map key
|
||||
string name = 1;
|
||||
// Mapped value
|
||||
RequestBodyOrReference value = 2;
|
||||
}
|
||||
|
||||
// Automatically-generated message used to represent maps of ResponseOrReference as ordered (name,value) pairs.
|
||||
message NamedResponseOrReference {
|
||||
// Map key
|
||||
string name = 1;
|
||||
// Mapped value
|
||||
ResponseOrReference value = 2;
|
||||
}
|
||||
|
||||
// Automatically-generated message used to represent maps of SchemaOrReference as ordered (name,value) pairs.
|
||||
message NamedSchemaOrReference {
|
||||
// Map key
|
||||
string name = 1;
|
||||
// Mapped value
|
||||
SchemaOrReference value = 2;
|
||||
}
|
||||
|
||||
// Automatically-generated message used to represent maps of SecuritySchemeOrReference as ordered (name,value) pairs.
|
||||
message NamedSecuritySchemeOrReference {
|
||||
// Map key
|
||||
string name = 1;
|
||||
// Mapped value
|
||||
SecuritySchemeOrReference value = 2;
|
||||
}
|
||||
|
||||
// Automatically-generated message used to represent maps of ServerVariable as ordered (name,value) pairs.
|
||||
message NamedServerVariable {
|
||||
// Map key
|
||||
string name = 1;
|
||||
// Mapped value
|
||||
ServerVariable value = 2;
|
||||
}
|
||||
|
||||
// Automatically-generated message used to represent maps of string as ordered (name,value) pairs.
|
||||
message NamedString {
|
||||
// Map key
|
||||
string name = 1;
|
||||
// Mapped value
|
||||
string value = 2;
|
||||
}
|
||||
|
||||
// Automatically-generated message used to represent maps of StringArray as ordered (name,value) pairs.
|
||||
message NamedStringArray {
|
||||
// Map key
|
||||
string name = 1;
|
||||
// Mapped value
|
||||
StringArray value = 2;
|
||||
}
|
||||
|
||||
// Configuration details for a supported OAuth Flow
|
||||
message OauthFlow {
|
||||
string authorization_url = 1;
|
||||
string token_url = 2;
|
||||
string refresh_url = 3;
|
||||
Strings scopes = 4;
|
||||
repeated NamedAny specification_extension = 5;
|
||||
}
|
||||
|
||||
// Allows configuration of the supported OAuth Flows.
|
||||
message OauthFlows {
|
||||
OauthFlow implicit = 1;
|
||||
OauthFlow password = 2;
|
||||
OauthFlow client_credentials = 3;
|
||||
OauthFlow authorization_code = 4;
|
||||
repeated NamedAny specification_extension = 5;
|
||||
}
|
||||
|
||||
message Object {
|
||||
repeated NamedAny additional_properties = 1;
|
||||
}
|
||||
|
||||
// Describes a single API operation on a path.
|
||||
message Operation {
|
||||
repeated string tags = 1;
|
||||
string summary = 2;
|
||||
string description = 3;
|
||||
ExternalDocs external_docs = 4;
|
||||
string operation_id = 5;
|
||||
repeated ParameterOrReference parameters = 6;
|
||||
RequestBodyOrReference request_body = 7;
|
||||
Responses responses = 8;
|
||||
CallbacksOrReferences callbacks = 9;
|
||||
bool deprecated = 10;
|
||||
repeated SecurityRequirement security = 11;
|
||||
repeated Server servers = 12;
|
||||
repeated NamedAny specification_extension = 13;
|
||||
}
|
||||
|
||||
// Describes a single operation parameter. A unique parameter is defined by a combination of a name and location.
|
||||
message Parameter {
|
||||
string name = 1;
|
||||
string in = 2;
|
||||
string description = 3;
|
||||
bool required = 4;
|
||||
bool deprecated = 5;
|
||||
bool allow_empty_value = 6;
|
||||
string style = 7;
|
||||
bool explode = 8;
|
||||
bool allow_reserved = 9;
|
||||
SchemaOrReference schema = 10;
|
||||
Any example = 11;
|
||||
ExamplesOrReferences examples = 12;
|
||||
MediaTypes content = 13;
|
||||
repeated NamedAny specification_extension = 14;
|
||||
}
|
||||
|
||||
message ParameterOrReference {
|
||||
oneof oneof {
|
||||
Parameter parameter = 1;
|
||||
Reference reference = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message ParametersOrReferences {
|
||||
repeated NamedParameterOrReference additional_properties = 1;
|
||||
}
|
||||
|
||||
// Describes the operations available on a single path. A Path Item MAY be empty, due to ACL constraints. The path itself is still exposed to the documentation viewer but they will not know which operations and parameters are available.
|
||||
message PathItem {
|
||||
string _ref = 1;
|
||||
string summary = 2;
|
||||
string description = 3;
|
||||
Operation get = 4;
|
||||
Operation put = 5;
|
||||
Operation post = 6;
|
||||
Operation delete = 7;
|
||||
Operation options = 8;
|
||||
Operation head = 9;
|
||||
Operation patch = 10;
|
||||
Operation trace = 11;
|
||||
repeated Server servers = 12;
|
||||
repeated ParameterOrReference parameters = 13;
|
||||
repeated NamedAny specification_extension = 14;
|
||||
}
|
||||
|
||||
// Holds the relative paths to the individual endpoints and their operations. The path is appended to the URL from the `Server Object` in order to construct the full URL. The Paths MAY be empty, due to ACL constraints.
|
||||
message Paths {
|
||||
repeated NamedPathItem path = 1;
|
||||
repeated NamedAny specification_extension = 2;
|
||||
}
|
||||
|
||||
message Properties {
|
||||
repeated NamedSchemaOrReference additional_properties = 1;
|
||||
}
|
||||
|
||||
// A simple object to allow referencing other components in the specification, internally and externally. The Reference Object is defined by JSON Reference and follows the same structure, behavior and rules. For this specification, reference resolution is accomplished as defined by the JSON Reference specification and not by the JSON Schema specification.
|
||||
message Reference {
|
||||
string _ref = 1;
|
||||
}
|
||||
|
||||
message RequestBodiesOrReferences {
|
||||
repeated NamedRequestBodyOrReference additional_properties = 1;
|
||||
}
|
||||
|
||||
// Describes a single request body.
|
||||
message RequestBody {
|
||||
string description = 1;
|
||||
MediaTypes content = 2;
|
||||
bool required = 3;
|
||||
repeated NamedAny specification_extension = 4;
|
||||
}
|
||||
|
||||
message RequestBodyOrReference {
|
||||
oneof oneof {
|
||||
RequestBody request_body = 1;
|
||||
Reference reference = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Describes a single response from an API Operation, including design-time, static `links` to operations based on the response.
|
||||
message Response {
|
||||
string description = 1;
|
||||
HeadersOrReferences headers = 2;
|
||||
MediaTypes content = 3;
|
||||
LinksOrReferences links = 4;
|
||||
repeated NamedAny specification_extension = 5;
|
||||
}
|
||||
|
||||
message ResponseOrReference {
|
||||
oneof oneof {
|
||||
Response response = 1;
|
||||
Reference reference = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// A container for the expected responses of an operation. The container maps a HTTP response code to the expected response. The documentation is not necessarily expected to cover all possible HTTP response codes because they may not be known in advance. However, documentation is expected to cover a successful operation response and any known errors. The `default` MAY be used as a default response object for all HTTP codes that are not covered individually by the specification. The `Responses Object` MUST contain at least one response code, and it SHOULD be the response for a successful operation call.
|
||||
message Responses {
|
||||
ResponseOrReference default = 1;
|
||||
repeated NamedResponseOrReference response_or_reference = 2;
|
||||
repeated NamedAny specification_extension = 3;
|
||||
}
|
||||
|
||||
message ResponsesOrReferences {
|
||||
repeated NamedResponseOrReference additional_properties = 1;
|
||||
}
|
||||
|
||||
// The Schema Object allows the definition of input and output data types. These types can be objects, but also primitives and arrays. This object is an extended subset of the JSON Schema Specification Wright Draft 00. For more information about the properties, see JSON Schema Core and JSON Schema Validation. Unless stated otherwise, the property definitions follow the JSON Schema.
|
||||
message Schema {
|
||||
bool nullable = 1;
|
||||
Discriminator discriminator = 2;
|
||||
bool read_only = 3;
|
||||
bool write_only = 4;
|
||||
Xml xml = 5;
|
||||
ExternalDocs external_docs = 6;
|
||||
Any example = 7;
|
||||
bool deprecated = 8;
|
||||
string title = 9;
|
||||
double multiple_of = 10;
|
||||
double maximum = 11;
|
||||
bool exclusive_maximum = 12;
|
||||
double minimum = 13;
|
||||
bool exclusive_minimum = 14;
|
||||
int64 max_length = 15;
|
||||
int64 min_length = 16;
|
||||
string pattern = 17;
|
||||
int64 max_items = 18;
|
||||
int64 min_items = 19;
|
||||
bool unique_items = 20;
|
||||
int64 max_properties = 21;
|
||||
int64 min_properties = 22;
|
||||
repeated string required = 23;
|
||||
repeated Any enum = 24;
|
||||
string type = 25;
|
||||
repeated SchemaOrReference all_of = 26;
|
||||
repeated SchemaOrReference one_of = 27;
|
||||
repeated SchemaOrReference any_of = 28;
|
||||
Schema not = 29;
|
||||
ItemsItem items = 30;
|
||||
Properties properties = 31;
|
||||
AdditionalPropertiesItem additional_properties = 32;
|
||||
DefaultType default = 33;
|
||||
string description = 34;
|
||||
string format = 35;
|
||||
repeated NamedAny specification_extension = 36;
|
||||
}
|
||||
|
||||
message SchemaOrReference {
|
||||
oneof oneof {
|
||||
Schema schema = 1;
|
||||
Reference reference = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message SchemasOrReferences {
|
||||
repeated NamedSchemaOrReference additional_properties = 1;
|
||||
}
|
||||
|
||||
// Lists the required security schemes to execute this operation. The name used for each property MUST correspond to a security scheme declared in the Security Schemes under the Components Object. Security Requirement Objects that contain multiple schemes require that all schemes MUST be satisfied for a request to be authorized. This enables support for scenarios where multiple query parameters or HTTP headers are required to convey security information. When a list of Security Requirement Objects is defined on the OpenAPI Object or Operation Object, only one of the Security Requirement Objects in the list needs to be satisfied to authorize the request.
|
||||
message SecurityRequirement {
|
||||
repeated NamedStringArray additional_properties = 1;
|
||||
}
|
||||
|
||||
// Defines a security scheme that can be used by the operations. Supported schemes are HTTP authentication, an API key (either as a header, a cookie parameter or as a query parameter), mutual TLS (use of a client certificate), OAuth2's common flows (implicit, password, application and access code) as defined in RFC6749, and OpenID Connect. Please note that currently (2019) the implicit flow is about to be deprecated OAuth 2.0 Security Best Current Practice. Recommended for most use case is Authorization Code Grant flow with PKCE.
|
||||
message SecurityScheme {
|
||||
string type = 1;
|
||||
string description = 2;
|
||||
string name = 3;
|
||||
string in = 4;
|
||||
string scheme = 5;
|
||||
string bearer_format = 6;
|
||||
OauthFlows flows = 7;
|
||||
string open_id_connect_url = 8;
|
||||
repeated NamedAny specification_extension = 9;
|
||||
}
|
||||
|
||||
message SecuritySchemeOrReference {
|
||||
oneof oneof {
|
||||
SecurityScheme security_scheme = 1;
|
||||
Reference reference = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message SecuritySchemesOrReferences {
|
||||
repeated NamedSecuritySchemeOrReference additional_properties = 1;
|
||||
}
|
||||
|
||||
// An object representing a Server.
|
||||
message Server {
|
||||
string url = 1;
|
||||
string description = 2;
|
||||
ServerVariables variables = 3;
|
||||
repeated NamedAny specification_extension = 4;
|
||||
}
|
||||
|
||||
// An object representing a Server Variable for server URL template substitution.
|
||||
message ServerVariable {
|
||||
repeated string enum = 1;
|
||||
string default = 2;
|
||||
string description = 3;
|
||||
repeated NamedAny specification_extension = 4;
|
||||
}
|
||||
|
||||
message ServerVariables {
|
||||
repeated NamedServerVariable additional_properties = 1;
|
||||
}
|
||||
|
||||
// Any property starting with x- is valid.
|
||||
message SpecificationExtension {
|
||||
oneof oneof {
|
||||
double number = 1;
|
||||
bool boolean = 2;
|
||||
string string = 3;
|
||||
}
|
||||
}
|
||||
|
||||
message StringArray {
|
||||
repeated string value = 1;
|
||||
}
|
||||
|
||||
message Strings {
|
||||
repeated NamedString additional_properties = 1;
|
||||
}
|
||||
|
||||
// Adds metadata to a single tag that is used by the Operation Object. It is not mandatory to have a Tag Object per tag defined in the Operation Object instances.
|
||||
message Tag {
|
||||
string name = 1;
|
||||
string description = 2;
|
||||
ExternalDocs external_docs = 3;
|
||||
repeated NamedAny specification_extension = 4;
|
||||
}
|
||||
|
||||
// A metadata object that allows for more fine-tuned XML model definitions. When using arrays, XML element names are *not* inferred (for singular/plural forms) and the `name` property SHOULD be used to add that information. See examples for expected behavior.
|
||||
message Xml {
|
||||
string name = 1;
|
||||
string namespace = 2;
|
||||
string prefix = 3;
|
||||
bool attribute = 4;
|
||||
bool wrapped = 5;
|
||||
repeated NamedAny specification_extension = 6;
|
||||
}
|
||||
|
21
vendor/github.com/googleapis/gnostic/openapiv3/README.md
generated
vendored
Normal file
21
vendor/github.com/googleapis/gnostic/openapiv3/README.md
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# OpenAPI v3 Protocol Buffer Models
|
||||
|
||||
This directory contains a Protocol Buffer-language model and related code for
|
||||
supporting OpenAPI v3.
|
||||
|
||||
Gnostic applications and plugins can use OpenAPIv3.proto to generate Protocol
|
||||
Buffer support code for their preferred languages.
|
||||
|
||||
OpenAPIv3.go is used by Gnostic to read JSON and YAML OpenAPI descriptions into
|
||||
the Protocol Buffer-based datastructures generated from OpenAPIv3.proto.
|
||||
|
||||
OpenAPIv3.proto and OpenAPIv3.go are generated by the Gnostic compiler
|
||||
generator, and OpenAPIv3.pb.go is generated by protoc, the Protocol Buffer
|
||||
compiler, and protoc-gen-go, the Protocol Buffer Go code generation plugin.
|
||||
|
||||
openapi-3.1.json is a JSON schema for OpenAPI 3.1 that is automatically
|
||||
generated from the OpenAPI 3.1 specification. It is not an official JSON Schema
|
||||
for OpenAPI.
|
||||
|
||||
The schema-generator directory contains support code which generates
|
||||
openapi-3.1.json from the OpenAPI 3.1 specification document (Markdown).
|
41
vendor/github.com/googleapis/gnostic/openapiv3/document.go
generated
vendored
Normal file
41
vendor/github.com/googleapis/gnostic/openapiv3/document.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright 2020 Google LLC. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package openapi_v3
|
||||
|
||||
import (
|
||||
"github.com/googleapis/gnostic/compiler"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// ParseDocument reads an OpenAPI v3 description from a YAML/JSON representation.
|
||||
func ParseDocument(b []byte) (*Document, error) {
|
||||
info, err := compiler.ReadInfoFromBytes("", b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
root := info.Content[0]
|
||||
return NewDocument(root, compiler.NewContextWithExtensions("$root", root, nil, nil))
|
||||
}
|
||||
|
||||
// YAMLValue produces a serialized YAML representation of the document.
|
||||
func (d *Document) YAMLValue(comment string) ([]byte, error) {
|
||||
rawInfo := d.ToRawInfo()
|
||||
rawInfo = &yaml.Node{
|
||||
Kind: yaml.DocumentNode,
|
||||
Content: []*yaml.Node{rawInfo},
|
||||
HeadComment: comment,
|
||||
}
|
||||
return yaml.Marshal(rawInfo)
|
||||
}
|
1245
vendor/github.com/googleapis/gnostic/openapiv3/openapi-3.0.json
generated
vendored
Normal file
1245
vendor/github.com/googleapis/gnostic/openapiv3/openapi-3.0.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1244
vendor/github.com/googleapis/gnostic/openapiv3/openapi-3.1.json
generated
vendored
Normal file
1244
vendor/github.com/googleapis/gnostic/openapiv3/openapi-3.1.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
410
vendor/k8s.io/kube-openapi/pkg/builder3/openapi.go
generated
vendored
Normal file
410
vendor/k8s.io/kube-openapi/pkg/builder3/openapi.go
generated
vendored
Normal file
@@ -0,0 +1,410 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package builder3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
restful "github.com/emicklei/go-restful"
|
||||
"k8s.io/kube-openapi/pkg/common"
|
||||
"k8s.io/kube-openapi/pkg/spec3"
|
||||
"k8s.io/kube-openapi/pkg/util"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
OpenAPIVersion = "3.0"
|
||||
)
|
||||
|
||||
type openAPI struct {
|
||||
config *common.Config
|
||||
spec *spec3.OpenAPI
|
||||
definitions map[string]common.OpenAPIDefinition
|
||||
}
|
||||
|
||||
func groupRoutesByPath(routes []restful.Route) map[string][]restful.Route {
|
||||
pathToRoutes := make(map[string][]restful.Route)
|
||||
for _, r := range routes {
|
||||
pathToRoutes[r.Path] = append(pathToRoutes[r.Path], r)
|
||||
}
|
||||
return pathToRoutes
|
||||
}
|
||||
|
||||
func (o *openAPI) buildResponse(model interface{}, description string, content []string) (*spec3.Response, error) {
|
||||
response := &spec3.Response{
|
||||
ResponseProps: spec3.ResponseProps{
|
||||
Description: description,
|
||||
Content: make(map[string]*spec3.MediaType),
|
||||
},
|
||||
}
|
||||
|
||||
s, err := o.toSchema(util.GetCanonicalTypeName(model))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, contentType := range content {
|
||||
response.ResponseProps.Content[contentType] = &spec3.MediaType{
|
||||
MediaTypeProps: spec3.MediaTypeProps{
|
||||
Schema: s,
|
||||
},
|
||||
}
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (o *openAPI) buildOperations(route restful.Route, inPathCommonParamsMap map[interface{}]*spec3.Parameter) (*spec3.Operation, error) {
|
||||
ret := &spec3.Operation{
|
||||
OperationProps: spec3.OperationProps{
|
||||
Description: route.Doc,
|
||||
Responses: &spec3.Responses{
|
||||
ResponsesProps: spec3.ResponsesProps{
|
||||
StatusCodeResponses: make(map[int]*spec3.Response),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
var err error
|
||||
if ret.OperationId, ret.Tags, err = o.config.GetOperationIDAndTags(&route); err != nil {
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Build responses
|
||||
for _, resp := range route.ResponseErrors {
|
||||
ret.Responses.StatusCodeResponses[resp.Code], err = o.buildResponse(resp.Model, resp.Message, route.Produces)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
}
|
||||
|
||||
// If there is no response but a write sample, assume that write sample is an http.StatusOK response.
|
||||
if len(ret.Responses.StatusCodeResponses) == 0 && route.WriteSample != nil {
|
||||
ret.Responses.StatusCodeResponses[http.StatusOK], err = o.buildResponse(route.WriteSample, "OK", route.Produces)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Default response if needed. Common Response config
|
||||
|
||||
ret.Parameters = make([]*spec3.Parameter, 0)
|
||||
for _, param := range route.ParameterDocs {
|
||||
_, isCommon := inPathCommonParamsMap[mapKeyFromParam(param)]
|
||||
if !isCommon && param.Data().Kind != restful.BodyParameterKind {
|
||||
openAPIParam, err := o.buildParameter(param.Data())
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
ret.Parameters = append(ret.Parameters, openAPIParam)
|
||||
}
|
||||
}
|
||||
|
||||
body, err := o.buildRequestBody(route.ParameterDocs, route.ReadSample)
|
||||
if err != nil {
|
||||
return nil ,err
|
||||
}
|
||||
|
||||
if body != nil {
|
||||
ret.RequestBody = body
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (o *openAPI) buildRequestBody(parameters []*restful.Parameter, bodySample interface{}) (*spec3.RequestBody, error) {
|
||||
for _, param := range parameters {
|
||||
if param.Data().Kind == restful.BodyParameterKind && bodySample != nil {
|
||||
schema, err := o.toSchema(util.GetCanonicalTypeName(bodySample))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r := &spec3.RequestBody{
|
||||
RequestBodyProps: spec3.RequestBodyProps{
|
||||
Content: map[string]*spec3.MediaType{
|
||||
"application/json": &spec3.MediaType{
|
||||
MediaTypeProps: spec3.MediaTypeProps{
|
||||
Schema: schema,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func newOpenAPI(config *common.Config) openAPI {
|
||||
o := openAPI{
|
||||
config: config,
|
||||
spec: &spec3.OpenAPI{
|
||||
Version: "3.0.0",
|
||||
Info: config.Info,
|
||||
Paths: &spec3.Paths{
|
||||
Paths: map[string]*spec3.Path{},
|
||||
},
|
||||
Components: &spec3.Components{
|
||||
Schemas: map[string]*spec.Schema{},
|
||||
},
|
||||
},
|
||||
}
|
||||
if o.config.GetOperationIDAndTags == nil {
|
||||
o.config.GetOperationIDAndTags = func(r *restful.Route) (string, []string, error) {
|
||||
return r.Operation, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
if o.config.GetDefinitionName == nil {
|
||||
o.config.GetDefinitionName = func(name string) (string, spec.Extensions) {
|
||||
return name[strings.LastIndex(name, "/")+1:], nil
|
||||
}
|
||||
}
|
||||
|
||||
o.definitions = o.config.GetDefinitions(func(name string) spec.Ref {
|
||||
defName, _ := o.config.GetDefinitionName(name)
|
||||
return spec.MustCreateRef("#/components/schemas/" + common.EscapeJsonPointer(defName))
|
||||
})
|
||||
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *openAPI) buildOpenAPISpec(webServices []*restful.WebService) error {
|
||||
pathsToIgnore := util.NewTrie(o.config.IgnorePrefixes)
|
||||
for _, w := range webServices {
|
||||
rootPath := w.RootPath()
|
||||
if pathsToIgnore.HasPrefix(rootPath) {
|
||||
continue
|
||||
}
|
||||
|
||||
commonParams, err := o.buildParameters(w.PathParameters())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for path, routes := range groupRoutesByPath(w.Routes()) {
|
||||
// go-swagger has special variable definition {$NAME:*} that can only be
|
||||
// used at the end of the path and it is not recognized by OpenAPI.
|
||||
if strings.HasSuffix(path, ":*}") {
|
||||
path = path[:len(path)-3] + "}"
|
||||
}
|
||||
if pathsToIgnore.HasPrefix(path) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Aggregating common parameters make API spec (and generated clients) simpler
|
||||
inPathCommonParamsMap, err := o.findCommonParameters(routes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pathItem, exists := o.spec.Paths.Paths[path]
|
||||
if exists {
|
||||
return fmt.Errorf("duplicate webservice route has been found for path: %v", path)
|
||||
}
|
||||
|
||||
pathItem = &spec3.Path{
|
||||
PathProps: spec3.PathProps{
|
||||
Parameters: make([]*spec3.Parameter, 0),
|
||||
},
|
||||
}
|
||||
|
||||
// add web services's parameters as well as any parameters appears in all ops, as common parameters
|
||||
pathItem.Parameters = append(pathItem.Parameters, commonParams...)
|
||||
for _, p := range inPathCommonParamsMap {
|
||||
pathItem.Parameters = append(pathItem.Parameters, p)
|
||||
}
|
||||
sortParameters(pathItem.Parameters)
|
||||
|
||||
for _, route := range routes {
|
||||
op, _ := o.buildOperations(route, inPathCommonParamsMap)
|
||||
|
||||
switch strings.ToUpper(route.Method) {
|
||||
case "GET":
|
||||
pathItem.Get = op
|
||||
case "POST":
|
||||
pathItem.Post = op
|
||||
case "HEAD":
|
||||
pathItem.Head = op
|
||||
case "PUT":
|
||||
pathItem.Put = op
|
||||
case "DELETE":
|
||||
pathItem.Delete = op
|
||||
case "OPTIONS":
|
||||
pathItem.Options = op
|
||||
case "PATCH":
|
||||
pathItem.Patch = op
|
||||
}
|
||||
|
||||
}
|
||||
o.spec.Paths.Paths[path] = pathItem
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func BuildOpenAPISpec(webServices []*restful.WebService, config *common.Config) (*spec3.OpenAPI, error) {
|
||||
a := newOpenAPI(config)
|
||||
err := a.buildOpenAPISpec(webServices)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return a.spec, nil
|
||||
}
|
||||
|
||||
func (o *openAPI) findCommonParameters(routes []restful.Route) (map[interface{}]*spec3.Parameter, error) {
|
||||
commonParamsMap := make(map[interface{}]*spec3.Parameter, 0)
|
||||
paramOpsCountByName := make(map[interface{}]int, 0)
|
||||
paramNameKindToDataMap := make(map[interface{}]restful.ParameterData, 0)
|
||||
for _, route := range routes {
|
||||
routeParamDuplicateMap := make(map[interface{}]bool)
|
||||
s := ""
|
||||
for _, param := range route.ParameterDocs {
|
||||
m, _ := json.Marshal(param.Data())
|
||||
s += string(m) + "\n"
|
||||
key := mapKeyFromParam(param)
|
||||
if routeParamDuplicateMap[key] {
|
||||
msg, _ := json.Marshal(route.ParameterDocs)
|
||||
return commonParamsMap, fmt.Errorf("duplicate parameter %v for route %v, %v", param.Data().Name, string(msg), s)
|
||||
}
|
||||
routeParamDuplicateMap[key] = true
|
||||
paramOpsCountByName[key]++
|
||||
paramNameKindToDataMap[key] = param.Data()
|
||||
}
|
||||
}
|
||||
for key, count := range paramOpsCountByName {
|
||||
paramData := paramNameKindToDataMap[key]
|
||||
if count == len(routes) && paramData.Kind != restful.BodyParameterKind {
|
||||
openAPIParam, err := o.buildParameter(paramData)
|
||||
if err != nil {
|
||||
return commonParamsMap, err
|
||||
}
|
||||
commonParamsMap[key] = openAPIParam
|
||||
}
|
||||
}
|
||||
return commonParamsMap, nil
|
||||
}
|
||||
|
||||
func (o *openAPI) buildParameters(restParam []*restful.Parameter) (ret []*spec3.Parameter, err error) {
|
||||
ret = make([]*spec3.Parameter, len(restParam))
|
||||
for i, v := range restParam {
|
||||
ret[i], err = o.buildParameter(v.Data())
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (o *openAPI) buildParameter(restParam restful.ParameterData) (ret *spec3.Parameter, err error) {
|
||||
ret = &spec3.Parameter{
|
||||
ParameterProps: spec3.ParameterProps{
|
||||
Name: restParam.Name,
|
||||
Description: restParam.Description,
|
||||
Required: restParam.Required,
|
||||
},
|
||||
}
|
||||
switch restParam.Kind {
|
||||
case restful.BodyParameterKind:
|
||||
return nil, nil
|
||||
case restful.PathParameterKind:
|
||||
ret.In = "path"
|
||||
if !restParam.Required {
|
||||
return ret, fmt.Errorf("path parameters should be marked at required for parameter %v", restParam)
|
||||
}
|
||||
case restful.QueryParameterKind:
|
||||
ret.In = "query"
|
||||
case restful.HeaderParameterKind:
|
||||
ret.In = "header"
|
||||
/* TODO: add support for the cookie param */
|
||||
default:
|
||||
return ret, fmt.Errorf("unsupported restful parameter kind : %v", restParam.Kind)
|
||||
}
|
||||
openAPIType, openAPIFormat := common.OpenAPITypeFormat(restParam.DataType)
|
||||
if openAPIType == "" {
|
||||
return ret, fmt.Errorf("non-body Restful parameter type should be a simple type, but got : %v", restParam.DataType)
|
||||
}
|
||||
|
||||
ret.Schema = &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{openAPIType},
|
||||
Format: openAPIFormat,
|
||||
UniqueItems: !restParam.AllowMultiple,
|
||||
},
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (o *openAPI) buildDefinitionRecursively(name string) error {
|
||||
uniqueName, extensions := o.config.GetDefinitionName(name)
|
||||
if _, ok := o.spec.Components.Schemas[uniqueName]; ok {
|
||||
return nil
|
||||
}
|
||||
if item, ok := o.definitions[name]; ok {
|
||||
schema := &spec.Schema{
|
||||
VendorExtensible: item.Schema.VendorExtensible,
|
||||
SchemaProps: item.Schema.SchemaProps,
|
||||
SwaggerSchemaProps: item.Schema.SwaggerSchemaProps,
|
||||
}
|
||||
if extensions != nil {
|
||||
if schema.Extensions == nil {
|
||||
schema.Extensions = spec.Extensions{}
|
||||
}
|
||||
for k, v := range extensions {
|
||||
schema.Extensions[k] = v
|
||||
}
|
||||
}
|
||||
o.spec.Components.Schemas[uniqueName] = schema
|
||||
for _, v := range item.Dependencies {
|
||||
if err := o.buildDefinitionRecursively(v); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("cannot find model definition for %v. If you added a new type, you may need to add +k8s:openapi-gen=true to the package or type and run code-gen again", name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *openAPI) buildDefinitionForType(name string) (string, error) {
|
||||
if err := o.buildDefinitionRecursively(name); err != nil {
|
||||
return "", err
|
||||
}
|
||||
defName, _ := o.config.GetDefinitionName(name)
|
||||
return "#/components/schemas/" + common.EscapeJsonPointer(defName), nil
|
||||
}
|
||||
|
||||
func (o *openAPI) toSchema(name string) (_ *spec.Schema, err error) {
|
||||
if openAPIType, openAPIFormat := common.OpenAPITypeFormat(name); openAPIType != "" {
|
||||
return &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{openAPIType},
|
||||
Format: openAPIFormat,
|
||||
},
|
||||
}, nil
|
||||
} else {
|
||||
ref, err := o.buildDefinitionForType(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Ref: spec.MustCreateRef(ref),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
}
|
52
vendor/k8s.io/kube-openapi/pkg/builder3/util.go
generated
vendored
Normal file
52
vendor/k8s.io/kube-openapi/pkg/builder3/util.go
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package builder3
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/emicklei/go-restful"
|
||||
"k8s.io/kube-openapi/pkg/spec3"
|
||||
)
|
||||
|
||||
func mapKeyFromParam(param *restful.Parameter) interface{} {
|
||||
return struct {
|
||||
Name string
|
||||
Kind int
|
||||
}{
|
||||
Name: param.Data().Name,
|
||||
Kind: param.Data().Kind,
|
||||
}
|
||||
}
|
||||
|
||||
func (s parameters) Len() int { return len(s) }
|
||||
func (s parameters) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
type parameters []*spec3.Parameter
|
||||
|
||||
type byNameIn struct {
|
||||
parameters
|
||||
}
|
||||
|
||||
func (s byNameIn) Less(i, j int) bool {
|
||||
return s.parameters[i].Name < s.parameters[j].Name || (s.parameters[i].Name == s.parameters[j].Name && s.parameters[i].In < s.parameters[j].In)
|
||||
}
|
||||
|
||||
// SortParameters sorts parameters by Name and In fields.
|
||||
func sortParameters(p []*spec3.Parameter) {
|
||||
sort.Sort(byNameIn{p})
|
||||
}
|
248
vendor/k8s.io/kube-openapi/pkg/handler3/handler.go
generated
vendored
Normal file
248
vendor/k8s.io/kube-openapi/pkg/handler3/handler.go
generated
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package handler3
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"crypto/sha512"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"mime"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
openapi_v3 "github.com/googleapis/gnostic/openapiv3"
|
||||
"github.com/munnerz/goautoneg"
|
||||
"k8s.io/kube-openapi/pkg/common"
|
||||
"k8s.io/kube-openapi/pkg/spec3"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
const (
|
||||
jsonExt = ".json"
|
||||
|
||||
mimeJson = "application/json"
|
||||
// TODO(mehdy): change @68f4ded to a version tag when gnostic add version tags.
|
||||
mimePb = "application/com.github.googleapis.gnostic.OpenAPIv3@68f4ded+protobuf"
|
||||
mimePbGz = "application/x-gzip"
|
||||
|
||||
subTypeProtobuf = "com.github.proto-openapi.spec.v3@v1.0+protobuf"
|
||||
subTypeJSON = "json"
|
||||
)
|
||||
|
||||
// OpenAPIService is the service responsible for serving OpenAPI spec. It has
|
||||
// the ability to safely change the spec while serving it.
|
||||
// OpenAPI V3 currently does not use the lazy marshaling strategy that OpenAPI V2 is using
|
||||
type OpenAPIService struct {
|
||||
// rwMutex protects All members of this service.
|
||||
rwMutex sync.RWMutex
|
||||
lastModified time.Time
|
||||
v3Schema map[string]*OpenAPIV3Group
|
||||
}
|
||||
|
||||
type OpenAPIV3Group struct {
|
||||
rwMutex sync.RWMutex
|
||||
|
||||
lastModified time.Time
|
||||
|
||||
specBytes []byte
|
||||
specPb []byte
|
||||
specPbGz []byte
|
||||
|
||||
specBytesETag string
|
||||
specPbETag string
|
||||
specPbGzETag string
|
||||
}
|
||||
|
||||
func init() {
|
||||
mime.AddExtensionType(".json", mimeJson)
|
||||
mime.AddExtensionType(".pb-v1", mimePb)
|
||||
mime.AddExtensionType(".gz", mimePbGz)
|
||||
}
|
||||
|
||||
func computeETag(data []byte) string {
|
||||
return fmt.Sprintf("\"%X\"", sha512.Sum512(data))
|
||||
}
|
||||
|
||||
// NewOpenAPIService builds an OpenAPIService starting with the given spec.
|
||||
func NewOpenAPIService(spec *spec.Swagger) (*OpenAPIService, error) {
|
||||
o := &OpenAPIService{}
|
||||
o.v3Schema = make(map[string]*OpenAPIV3Group)
|
||||
return o, nil
|
||||
}
|
||||
|
||||
func (o *OpenAPIService) getGroupBytes() ([]byte, error) {
|
||||
o.rwMutex.RLock()
|
||||
defer o.rwMutex.RUnlock()
|
||||
keys := make([]string, len(o.v3Schema))
|
||||
i := 0
|
||||
for k := range o.v3Schema {
|
||||
keys[i] = k
|
||||
i++
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
group := make(map[string][]string)
|
||||
group["Paths"] = keys
|
||||
|
||||
j, err := json.Marshal(group)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return j, nil
|
||||
}
|
||||
|
||||
func (o *OpenAPIService) getSingleGroupBytes(getType string, group string) ([]byte, string, time.Time, error) {
|
||||
o.rwMutex.RLock()
|
||||
defer o.rwMutex.RUnlock()
|
||||
v, ok := o.v3Schema[group]
|
||||
if !ok {
|
||||
return nil, "", time.Now(), fmt.Errorf("Cannot find CRD group %s", group)
|
||||
}
|
||||
if getType == subTypeJSON {
|
||||
return v.specBytes, v.specBytesETag, v.lastModified, nil
|
||||
} else if getType == subTypeProtobuf {
|
||||
return v.specPb, v.specPbETag, v.lastModified, nil
|
||||
}
|
||||
return nil, "", time.Now(), fmt.Errorf("Invalid accept clause %s", getType)
|
||||
}
|
||||
|
||||
func (o *OpenAPIService) UpdateGroupVersion(group string, openapi *spec3.OpenAPI) (err error) {
|
||||
o.rwMutex.Lock()
|
||||
defer o.rwMutex.Unlock()
|
||||
|
||||
specBytes, err := json.Marshal(openapi)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, ok := o.v3Schema[group]; !ok {
|
||||
o.v3Schema[group] = &OpenAPIV3Group{}
|
||||
}
|
||||
return o.v3Schema[group].UpdateSpec(specBytes)
|
||||
}
|
||||
|
||||
func (o *OpenAPIService) DeleteGroupVersion(group string) {
|
||||
o.rwMutex.Lock()
|
||||
defer o.rwMutex.Unlock()
|
||||
delete(o.v3Schema, group)
|
||||
}
|
||||
|
||||
func ToV3ProtoBinary(json []byte) ([]byte, error) {
|
||||
document, err := openapi_v3.ParseDocument(json)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return proto.Marshal(document)
|
||||
}
|
||||
|
||||
func toGzip(data []byte) []byte {
|
||||
var buf bytes.Buffer
|
||||
zw := gzip.NewWriter(&buf)
|
||||
zw.Write(data)
|
||||
zw.Close()
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func (o *OpenAPIService) HandleDiscovery(w http.ResponseWriter, r *http.Request) {
|
||||
data, _ := o.getGroupBytes()
|
||||
http.ServeContent(w, r, "/openapi/v3", time.Now(), bytes.NewReader(data))
|
||||
}
|
||||
|
||||
func (o *OpenAPIService) HandleGroupVersion(w http.ResponseWriter, r *http.Request) {
|
||||
url := strings.SplitAfterN(r.URL.Path, "/", 4)
|
||||
group := url[3]
|
||||
|
||||
decipherableFormats := r.Header.Get("Accept")
|
||||
if decipherableFormats == "" {
|
||||
decipherableFormats = "*/*"
|
||||
}
|
||||
clauses := goautoneg.ParseAccept(decipherableFormats)
|
||||
w.Header().Add("Vary", "Accept")
|
||||
|
||||
if len(clauses) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
accepted := []struct {
|
||||
Type string
|
||||
SubType string
|
||||
}{
|
||||
{"application", subTypeJSON},
|
||||
{"application", subTypeProtobuf},
|
||||
}
|
||||
|
||||
for _, clause := range clauses {
|
||||
for _, accepts := range accepted {
|
||||
if clause.Type != accepts.Type && clause.Type != "*" {
|
||||
continue
|
||||
}
|
||||
if clause.SubType != accepts.SubType && clause.SubType != "*" {
|
||||
continue
|
||||
}
|
||||
data, etag, lastModified, err := o.getSingleGroupBytes(accepts.SubType, group)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
w.Header().Set("Etag", etag)
|
||||
http.ServeContent(w, r, "", lastModified, bytes.NewReader(data))
|
||||
return
|
||||
}
|
||||
}
|
||||
w.WriteHeader(406)
|
||||
return
|
||||
}
|
||||
|
||||
func (o *OpenAPIService) RegisterOpenAPIV3VersionedService(servePath string, handler common.PathHandlerByGroupVersion) error {
|
||||
handler.Handle(servePath, http.HandlerFunc(o.HandleDiscovery))
|
||||
handler.HandlePrefix(servePath+"/", http.HandlerFunc(o.HandleGroupVersion))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *OpenAPIV3Group) UpdateSpec(specBytes []byte) (err error) {
|
||||
o.rwMutex.Lock()
|
||||
defer o.rwMutex.Unlock()
|
||||
|
||||
specPb, err := ToV3ProtoBinary(specBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
specPbGz := toGzip(specPb)
|
||||
|
||||
specBytesETag := computeETag(specBytes)
|
||||
specPbETag := computeETag(specPb)
|
||||
specPbGzETag := computeETag(specPbGz)
|
||||
|
||||
lastModified := time.Now()
|
||||
|
||||
o.specBytes = specBytes
|
||||
o.specPb = specPb
|
||||
o.specPbGz = specPbGz
|
||||
|
||||
o.specBytesETag = specBytesETag
|
||||
o.specPbETag = specPbETag
|
||||
o.specPbGzETag = specPbGzETag
|
||||
|
||||
o.lastModified = lastModified
|
||||
return nil
|
||||
}
|
47
vendor/k8s.io/kube-openapi/pkg/spec3/component.go
generated
vendored
Normal file
47
vendor/k8s.io/kube-openapi/pkg/spec3/component.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package spec3
|
||||
|
||||
import "k8s.io/kube-openapi/pkg/validation/spec"
|
||||
|
||||
// Components holds a set of reusable objects for different aspects of the OAS.
|
||||
// All objects defined within the components object will have no effect on the API
|
||||
// unless they are explicitly referenced from properties outside the components object.
|
||||
//
|
||||
// more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#componentsObject
|
||||
type Components struct {
|
||||
// Schemas holds reusable Schema Objects
|
||||
Schemas map[string]*spec.Schema `json:"schemas,omitempty"`
|
||||
// SecuritySchemes holds reusable Security Scheme Objects, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securitySchemeObject
|
||||
SecuritySchemes SecuritySchemes `json:"securitySchemes,omitempty"`
|
||||
// Responses holds reusable Responses Objects
|
||||
Responses map[string]*Response `json:"responses,omitempty"`
|
||||
// Parameters holds reusable Parameters Objects
|
||||
Parameters map[string]*Parameter `json:"parameters,omitempty"`
|
||||
// Example holds reusable Example objects
|
||||
Examples map[string]*Example `json:"examples,omitempty"`
|
||||
// RequestBodies holds reusable Request Body objects
|
||||
RequestBodies map[string]*RequestBody `json:"requestBodies,omitempty"`
|
||||
// Links is a map of operations links that can be followed from the response
|
||||
Links map[string]*Link `json:"links,omitempty"`
|
||||
// Headers holds a maps of a headers name to its definition
|
||||
Headers map[string]*Header `json:"headers,omitempty"`
|
||||
// all fields are defined at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#componentsObject
|
||||
}
|
||||
|
||||
// SecuritySchemes holds reusable Security Scheme Objects, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securitySchemeObject
|
||||
type SecuritySchemes map[string]*SecurityScheme
|
64
vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go
generated
vendored
Normal file
64
vendor/k8s.io/kube-openapi/pkg/spec3/encoding.go
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package spec3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/go-openapi/swag"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
type Encoding struct {
|
||||
EncodingProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode Encoding as JSON
|
||||
func (e *Encoding) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(e.EncodingProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(e.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
func (e *Encoding) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &e.EncodingProps); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &e.VendorExtensible); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type EncodingProps struct {
|
||||
// Content Type for encoding a specific property
|
||||
ContentType string `json:"contentType,omitempty"`
|
||||
// A map allowing additional information to be provided as headers
|
||||
Headers map[string]*Header `json:"headers,omitempty"`
|
||||
// Describes how a specific property value will be serialized depending on its type
|
||||
Style string `json:"style,omitempty"`
|
||||
// When this is true, property values of type array or object generate separate parameters for each value of the array, or key-value-pair of the map. For other types of properties this property has no effect
|
||||
Explode string `json:"explode,omitempty"`
|
||||
// AllowReserved determines whether the parameter value SHOULD allow reserved characters, as defined by RFC3986
|
||||
AllowReserved bool `json:"allowReserved,omitempty"`
|
||||
}
|
73
vendor/k8s.io/kube-openapi/pkg/spec3/example.go
generated
vendored
Normal file
73
vendor/k8s.io/kube-openapi/pkg/spec3/example.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package spec3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// Example https://swagger.io/specification/#example-object
|
||||
|
||||
type Example struct {
|
||||
spec.Refable
|
||||
ExampleProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode RequestBody as JSON
|
||||
func (e *Example) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(e.Refable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(e.ExampleProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b3, err := json.Marshal(e.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2, b3), nil
|
||||
}
|
||||
|
||||
func (e *Example) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &e.Refable); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &e.ExampleProps); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &e.VendorExtensible); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ExampleProps struct {
|
||||
// Summary holds a short description of the example
|
||||
Summary string `json:"summary,omitempty"`
|
||||
// Description holds a long description of the example
|
||||
Description string `json:"description,omitempty"`
|
||||
// Embedded literal example.
|
||||
Value interface{} `json:"value,omitempty"`
|
||||
// A URL that points to the literal example. This provides the capability to reference examples that cannot easily be included in JSON or YAML documents.
|
||||
ExternalValue string `json:"externalValue,omitempty"`
|
||||
}
|
58
vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go
generated
vendored
Normal file
58
vendor/k8s.io/kube-openapi/pkg/spec3/external_documentation.go
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package spec3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
type ExternalDocumentation struct {
|
||||
ExternalDocumentationProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
type ExternalDocumentationProps struct {
|
||||
// Description is a short description of the target documentation. CommonMark syntax MAY be used for rich text representation.
|
||||
Description string `json:"description,omitempty"`
|
||||
// URL is the URL for the target documentation.
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode Responses as JSON
|
||||
func (e *ExternalDocumentation) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(e.ExternalDocumentationProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(e.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
func (e *ExternalDocumentation) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &e.ExternalDocumentationProps); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &e.VendorExtensible); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
90
vendor/k8s.io/kube-openapi/pkg/spec3/header.go
generated
vendored
Normal file
90
vendor/k8s.io/kube-openapi/pkg/spec3/header.go
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package spec3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/go-openapi/swag"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
// Header a struct that describes a single operation parameter, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#parameterObject
|
||||
//
|
||||
// Note that this struct is actually a thin wrapper around HeaderProps to make it referable and extensible
|
||||
type Header struct {
|
||||
spec.Refable
|
||||
HeaderProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode Header as JSON
|
||||
func (h *Header) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(h.Refable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(h.HeaderProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b3, err := json.Marshal(h.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2, b3), nil
|
||||
}
|
||||
|
||||
func (h *Header) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &h.Refable); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &h.HeaderProps); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &h.VendorExtensible); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// HeaderProps a struct that describes a header object
|
||||
type HeaderProps struct {
|
||||
// Description holds a brief description of the parameter
|
||||
Description string `json:"description,omitempty"`
|
||||
// Required determines whether this parameter is mandatory
|
||||
Required bool `json:"required,omitempty"`
|
||||
// Deprecated declares this operation to be deprecated
|
||||
Deprecated bool `json:"deprecated,omitempty"`
|
||||
// AllowEmptyValue sets the ability to pass empty-valued parameters
|
||||
AllowEmptyValue bool `json:"allowEmptyValue,omitempty"`
|
||||
// Style describes how the parameter value will be serialized depending on the type of the parameter value
|
||||
Style string `json:"style,omitempty"`
|
||||
// Explode when true, parameter values of type array or object generate separate parameters for each value of the array or key-value pair of the map
|
||||
Explode bool `json:"explode,omitempty"`
|
||||
// AllowReserved determines whether the parameter value SHOULD allow reserved characters, as defined by RFC3986
|
||||
AllowReserved bool `json:"allowReserved,omitempty"`
|
||||
// Schema holds the schema defining the type used for the parameter
|
||||
Schema *spec.Schema `json:"schema,omitempty"`
|
||||
// Content holds a map containing the representations for the parameter
|
||||
Content map[string]*MediaType `json:"content,omitempty"`
|
||||
// Example of the header
|
||||
Example interface{} `json:"example,omitempty"`
|
||||
// Examples of the header
|
||||
Examples map[string]*Example `json:"examples,omitempty"`
|
||||
}
|
66
vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go
generated
vendored
Normal file
66
vendor/k8s.io/kube-openapi/pkg/spec3/media_type.go
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package spec3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/go-openapi/swag"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
// MediaType a struct that allows you to specify content format, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#mediaTypeObject
|
||||
//
|
||||
// Note that this struct is actually a thin wrapper around MediaTypeProps to make it referable and extensible
|
||||
type MediaType struct {
|
||||
MediaTypeProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode MediaType as JSON
|
||||
func (m *MediaType) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(m.MediaTypeProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(m.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
func (m *MediaType) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &m.MediaTypeProps); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &m.VendorExtensible); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MediaTypeProps a struct that allows you to specify content format, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#mediaTypeObject
|
||||
type MediaTypeProps struct {
|
||||
// Schema holds the schema defining the type used for the media type
|
||||
Schema *spec.Schema `json:"schema,omitempty"`
|
||||
// Example of the media type
|
||||
Example interface{} `json:"example,omitempty"`
|
||||
// Examples of the media type. Each example object should match the media type and specific schema if present
|
||||
Examples map[string]*Example `json:"examples,omitempty"`
|
||||
// A map between a property name and its encoding information. The key, being the property name, MUST exist in the schema as a property. The encoding object SHALL only apply to requestBody objects when the media type is multipart or application/x-www-form-urlencoded
|
||||
Encoding map[string]*Encoding `json:"encoding,omitempty"`
|
||||
}
|
79
vendor/k8s.io/kube-openapi/pkg/spec3/operation.go
generated
vendored
Normal file
79
vendor/k8s.io/kube-openapi/pkg/spec3/operation.go
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package spec3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// Operation describes a single API operation on a path, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#operationObject
|
||||
//
|
||||
// Note that this struct is actually a thin wrapper around OperationProps to make it referable and extensible
|
||||
type Operation struct {
|
||||
OperationProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode Operation as JSON
|
||||
func (o *Operation) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(o.OperationProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(o.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON hydrates this items instance with the data from JSON
|
||||
func (o *Operation) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &o.OperationProps); err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(data, &o.VendorExtensible)
|
||||
}
|
||||
|
||||
// OperationProps describes a single API operation on a path, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#operationObject
|
||||
type OperationProps struct {
|
||||
// Tags holds a list of tags for API documentation control
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
// Summary holds a short summary of what the operation does
|
||||
Summary string `json:"summary,omitempty"`
|
||||
// Description holds a verbose explanation of the operation behavior
|
||||
Description string `json:"description,omitempty"`
|
||||
// ExternalDocs holds additional external documentation for this operation
|
||||
ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"`
|
||||
// OperationId holds a unique string used to identify the operation
|
||||
OperationId string `json:"operationId,omitempty"`
|
||||
// Parameters a list of parameters that are applicable for this operation
|
||||
Parameters []*Parameter `json:"parameters,omitempty"`
|
||||
// RequestBody holds the request body applicable for this operation
|
||||
RequestBody *RequestBody `json:"requestBody,omitempty"`
|
||||
// Responses holds the list of possible responses as they are returned from executing this operation
|
||||
Responses *Responses `json:"responses,omitempty"`
|
||||
// Deprecated declares this operation to be deprecated
|
||||
Deprecated bool `json:"deprecated,omitempty"`
|
||||
// SecurityRequirement holds a declaration of which security mechanisms can be used for this operation
|
||||
SecurityRequirement []*SecurityRequirement `json:"security,omitempty"`
|
||||
// Servers contains an alternative server array to service this operation
|
||||
Servers []*Server `json:"servers,omitempty"`
|
||||
}
|
94
vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go
generated
vendored
Normal file
94
vendor/k8s.io/kube-openapi/pkg/spec3/parameter.go
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package spec3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/go-openapi/swag"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
// Parameter a struct that describes a single operation parameter, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#parameterObject
|
||||
//
|
||||
// Note that this struct is actually a thin wrapper around ParameterProps to make it referable and extensible
|
||||
type Parameter struct {
|
||||
spec.Refable
|
||||
ParameterProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode Parameter as JSON
|
||||
func (p *Parameter) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(p.Refable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(p.ParameterProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b3, err := json.Marshal(p.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2, b3), nil
|
||||
}
|
||||
|
||||
func (p *Parameter) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &p.Refable); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &p.ParameterProps); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &p.VendorExtensible); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParameterProps a struct that describes a single operation parameter, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#parameterObject
|
||||
type ParameterProps struct {
|
||||
// Name holds the name of the parameter
|
||||
Name string `json:"name,omitempty"`
|
||||
// In holds the location of the parameter
|
||||
In string `json:"in,omitempty"`
|
||||
// Description holds a brief description of the parameter
|
||||
Description string `json:"description,omitempty"`
|
||||
// Required determines whether this parameter is mandatory
|
||||
Required bool `json:"required,omitempty"`
|
||||
// Deprecated declares this operation to be deprecated
|
||||
Deprecated bool `json:"deprecated,omitempty"`
|
||||
// AllowEmptyValue sets the ability to pass empty-valued parameters
|
||||
AllowEmptyValue bool `json:"allowEmptyValue,omitempty"`
|
||||
// Style describes how the parameter value will be serialized depending on the type of the parameter value
|
||||
Style string `json:"style,omitempty"`
|
||||
// Explode when true, parameter values of type array or object generate separate parameters for each value of the array or key-value pair of the map
|
||||
Explode bool `json:"explode,omitempty"`
|
||||
// AllowReserved determines whether the parameter value SHOULD allow reserved characters, as defined by RFC3986
|
||||
AllowReserved bool `json:"allowReserved,omitempty"`
|
||||
// Schema holds the schema defining the type used for the parameter
|
||||
Schema *spec.Schema `json:"schema,omitempty"`
|
||||
// Content holds a map containing the representations for the parameter
|
||||
Content map[string]*MediaType `json:"content,omitempty"`
|
||||
// Example of the parameter's potential value
|
||||
Example interface{} `json:"example,omitempty"`
|
||||
// Examples of the parameter's potential value. Each example SHOULD contain a value in the correct format as specified in the parameter encoding
|
||||
Examples map[string]*Example `json:"examples,omitempty"`
|
||||
}
|
142
vendor/k8s.io/kube-openapi/pkg/spec3/path.go
generated
vendored
Normal file
142
vendor/k8s.io/kube-openapi/pkg/spec3/path.go
generated
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package spec3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// Paths describes the available paths and operations for the API, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#pathsObject
|
||||
type Paths struct {
|
||||
Paths map[string]*Path
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode Paths as JSON
|
||||
func (p *Paths) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(p.Paths)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(p.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON hydrates this items instance with the data from JSON
|
||||
func (p *Paths) UnmarshalJSON(data []byte) error {
|
||||
var res map[string]json.RawMessage
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
for k, v := range res {
|
||||
if strings.HasPrefix(strings.ToLower(k), "x-") {
|
||||
if p.Extensions == nil {
|
||||
p.Extensions = make(map[string]interface{})
|
||||
}
|
||||
var d interface{}
|
||||
if err := json.Unmarshal(v, &d); err != nil {
|
||||
return err
|
||||
}
|
||||
p.Extensions[k] = d
|
||||
}
|
||||
if strings.HasPrefix(k, "/") {
|
||||
if p.Paths == nil {
|
||||
p.Paths = make(map[string]*Path)
|
||||
}
|
||||
var pi *Path
|
||||
if err := json.Unmarshal(v, &pi); err != nil {
|
||||
return err
|
||||
}
|
||||
p.Paths[k] = pi
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Path describes the operations available on a single path, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#pathItemObject
|
||||
//
|
||||
// Note that this struct is actually a thin wrapper around PathProps to make it referable and extensible
|
||||
type Path struct {
|
||||
spec.Refable
|
||||
PathProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode Path as JSON
|
||||
func (p *Path) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(p.Refable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(p.PathProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b3, err := json.Marshal(p.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2, b3), nil
|
||||
}
|
||||
|
||||
func (p *Path) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &p.Refable); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &p.PathProps); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &p.VendorExtensible); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PathProps describes the operations available on a single path, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#pathItemObject
|
||||
type PathProps struct {
|
||||
// Summary holds a summary for all operations in this path
|
||||
Summary string `json:"summary,omitempty"`
|
||||
// Description holds a description for all operations in this path
|
||||
Description string `json:"description,omitempty"`
|
||||
// Get defines GET operation
|
||||
Get *Operation `json:"get,omitempty"`
|
||||
// Put defines PUT operation
|
||||
Put *Operation `json:"put,omitempty"`
|
||||
// Post defines POST operation
|
||||
Post *Operation `json:"post,omitempty"`
|
||||
// Delete defines DELETE operation
|
||||
Delete *Operation `json:"delete,omitempty"`
|
||||
// Options defines OPTIONS operation
|
||||
Options *Operation `json:"options,omitempty"`
|
||||
// Head defines HEAD operation
|
||||
Head *Operation `json:"head,omitempty"`
|
||||
// Patch defines PATCH operation
|
||||
Patch *Operation `json:"patch,omitempty"`
|
||||
// Trace defines TRACE operation
|
||||
Trace *Operation `json:"trace,omitempty"`
|
||||
// Servers is an alternative server array to service all operations in this path
|
||||
Servers []*Server `json:"servers,omitempty"`
|
||||
// Parameters a list of parameters that are applicable for this operation
|
||||
Parameters []*Parameter `json:"parameters,omitempty"`
|
||||
}
|
73
vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go
generated
vendored
Normal file
73
vendor/k8s.io/kube-openapi/pkg/spec3/request_body.go
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package spec3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// RequestBody describes a single request body, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#requestBodyObject
|
||||
//
|
||||
// Note that this struct is actually a thin wrapper around RequestBodyProps to make it referable and extensible
|
||||
type RequestBody struct {
|
||||
spec.Refable
|
||||
RequestBodyProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode RequestBody as JSON
|
||||
func (r *RequestBody) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(r.Refable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(r.RequestBodyProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b3, err := json.Marshal(r.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2, b3), nil
|
||||
}
|
||||
|
||||
func (r *RequestBody) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &r.Refable); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &r.RequestBodyProps); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &r.VendorExtensible); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RequestBodyProps describes a single request body, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#requestBodyObject
|
||||
type RequestBodyProps struct {
|
||||
// Description holds a brief description of the request body
|
||||
Description string `json:"description,omitempty"`
|
||||
// Content is the content of the request body. The key is a media type or media type range and the value describes it
|
||||
Content map[string]*MediaType `json:"content,omitempty"`
|
||||
// Required determines if the request body is required in the request
|
||||
Required bool `json:"required,omitempty"`
|
||||
}
|
203
vendor/k8s.io/kube-openapi/pkg/spec3/response.go
generated
vendored
Normal file
203
vendor/k8s.io/kube-openapi/pkg/spec3/response.go
generated
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package spec3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// Responses holds the list of possible responses as they are returned from executing this operation
|
||||
//
|
||||
// Note that this struct is actually a thin wrapper around ResponsesProps to make it referable and extensible
|
||||
type Responses struct {
|
||||
ResponsesProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode Responses as JSON
|
||||
func (r *Responses) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(r.ResponsesProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(r.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
func (r *Responses) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &r.ResponsesProps); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &r.VendorExtensible); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResponsesProps holds the list of possible responses as they are returned from executing this operation
|
||||
type ResponsesProps struct {
|
||||
// Default holds the documentation of responses other than the ones declared for specific HTTP response codes. Use this field to cover undeclared responses
|
||||
Default *Response `json:"-"`
|
||||
// StatusCodeResponses holds a map of any HTTP status code to the response definition
|
||||
StatusCodeResponses map[int]*Response `json:"-"`
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode ResponsesProps as JSON
|
||||
func (r ResponsesProps) MarshalJSON() ([]byte, error) {
|
||||
toser := map[string]*Response{}
|
||||
if r.Default != nil {
|
||||
toser["default"] = r.Default
|
||||
}
|
||||
for k, v := range r.StatusCodeResponses {
|
||||
toser[strconv.Itoa(k)] = v
|
||||
}
|
||||
return json.Marshal(toser)
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals responses from JSON
|
||||
func (r *ResponsesProps) UnmarshalJSON(data []byte) error {
|
||||
var res map[string]*Response
|
||||
if err := json.Unmarshal(data, &res); err != nil {
|
||||
return nil
|
||||
}
|
||||
if v, ok := res["default"]; ok {
|
||||
r.Default = v
|
||||
delete(res, "default")
|
||||
}
|
||||
for k, v := range res {
|
||||
if nk, err := strconv.Atoi(k); err == nil {
|
||||
if r.StatusCodeResponses == nil {
|
||||
r.StatusCodeResponses = map[int]*Response{}
|
||||
}
|
||||
r.StatusCodeResponses[nk] = v
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Response describes a single response from an API Operation, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#responseObject
|
||||
//
|
||||
// Note that this struct is actually a thin wrapper around ResponseProps to make it referable and extensible
|
||||
type Response struct {
|
||||
spec.Refable
|
||||
ResponseProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode Response as JSON
|
||||
func (r *Response) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(r.Refable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(r.ResponseProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b3, err := json.Marshal(r.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2, b3), nil
|
||||
}
|
||||
|
||||
func (r *Response) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &r.Refable); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &r.ResponseProps); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &r.VendorExtensible); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResponseProps describes a single response from an API Operation, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#responseObject
|
||||
type ResponseProps struct {
|
||||
// Description holds a short description of the response
|
||||
Description string `json:"description,omitempty"`
|
||||
// Headers holds a maps of a headers name to its definition
|
||||
Headers map[string]*Header `json:"headers,omitempty"`
|
||||
// Content holds a map containing descriptions of potential response payloads
|
||||
Content map[string]*MediaType `json:"content,omitempty"`
|
||||
// Links is a map of operations links that can be followed from the response
|
||||
Links map[string]*Link `json:"links,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
// Link represents a possible design-time link for a response, more at https://swagger.io/specification/#link-object
|
||||
type Link struct {
|
||||
spec.Refable
|
||||
LinkProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode Link as JSON
|
||||
func (r *Link) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(r.Refable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(r.LinkProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b3, err := json.Marshal(r.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2, b3), nil
|
||||
}
|
||||
|
||||
func (r *Link) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &r.Refable); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &r.LinkProps); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &r.VendorExtensible); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// LinkProps describes a single response from an API Operation, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#responseObject
|
||||
type LinkProps struct {
|
||||
// OperationId is the name of an existing, resolvable OAS operation
|
||||
OperationId string `json:"operationId,omitempty"`
|
||||
// Parameters is a map representing parameters to pass to an operation as specified with operationId or identified via operationRef
|
||||
Parameters map[string]interface{} `json:"parameters,omitempty"`
|
||||
// Description holds a description of the link
|
||||
Description string `json:"description,omitempty"`
|
||||
// RequestBody is a literal value or expresion to use as a request body when calling the target operation
|
||||
RequestBody interface{} `json:"requestBody,omitempty"`
|
||||
// Server holds a server object used by the target operation
|
||||
Server *Server `json:"server,omitempty"`
|
||||
}
|
56
vendor/k8s.io/kube-openapi/pkg/spec3/security_requirement.go
generated
vendored
Normal file
56
vendor/k8s.io/kube-openapi/pkg/spec3/security_requirement.go
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package spec3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// SecurityRequirementProps describes the required security schemes to execute an operation, more at https://swagger.io/specification/#security-requirement-object
|
||||
//
|
||||
// Note that this struct is actually a thin wrapper around SecurityRequirementProps to make it referable and extensible
|
||||
type SecurityRequirement struct {
|
||||
SecurityRequirementProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode SecurityRequirement as JSON
|
||||
func (s *SecurityRequirement) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(s.SecurityRequirementProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(s.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON hydrates this items instance with the data from JSON
|
||||
func (s *SecurityRequirement) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &s.SecurityRequirementProps); err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(data, &s.VendorExtensible)
|
||||
}
|
||||
|
||||
// SecurityRequirementProps describes the required security schemes to execute an operation, more at https://swagger.io/specification/#security-requirement-object
|
||||
type SecurityRequirementProps map[string][]string
|
118
vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go
generated
vendored
Normal file
118
vendor/k8s.io/kube-openapi/pkg/spec3/security_scheme.go
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package spec3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// SecurityScheme defines reusable Security Scheme Object, more at https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#securitySchemeObject
|
||||
type SecurityScheme struct {
|
||||
spec.Refable
|
||||
SecuritySchemeProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode SecurityScheme as JSON
|
||||
func (s *SecurityScheme) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(s.SecuritySchemeProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(s.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b3, err := json.Marshal(s.Refable)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2, b3), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON hydrates this items instance with the data from JSON
|
||||
func (s *SecurityScheme) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &s.SecuritySchemeProps); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &s.VendorExtensible); err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(data, &s.Refable)
|
||||
}
|
||||
|
||||
// SecuritySchemeProps defines a security scheme that can be used by the operations
|
||||
type SecuritySchemeProps struct {
|
||||
// Type of the security scheme
|
||||
Type string `json:"type,omitempty"`
|
||||
// Description holds a short description for security scheme
|
||||
Description string `json:"description,omitempty"`
|
||||
// Name holds the name of the header, query or cookie parameter to be used
|
||||
Name string `json:"name,omitempty"`
|
||||
// In holds the location of the API key
|
||||
In string `json:"in,omitempty"`
|
||||
// Scheme holds the name of the HTTP Authorization scheme to be used in the Authorization header
|
||||
Scheme string `json:"scheme,omitempty"`
|
||||
// BearerFormat holds a hint to the client to identify how the bearer token is formatted
|
||||
BearerFormat string `json:"bearerFormat,omitempty"`
|
||||
// Flows contains configuration information for the flow types supported.
|
||||
Flows map[string]*OAuthFlow `json:"flows,omitempty"`
|
||||
// OpenIdConnectUrl holds an url to discover OAuth2 configuration values from
|
||||
OpenIdConnectUrl string `json:"openIdConnectUrl,omitempty"`
|
||||
}
|
||||
|
||||
// OAuthFlow contains configuration information for the flow types supported.
|
||||
type OAuthFlow struct {
|
||||
OAuthFlowProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode OAuthFlow as JSON
|
||||
func (o *OAuthFlow) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(o.OAuthFlowProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(o.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON hydrates this items instance with the data from JSON
|
||||
func (o *OAuthFlow) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &o.OAuthFlowProps); err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(data, &o.VendorExtensible)
|
||||
}
|
||||
|
||||
// OAuthFlowProps holds configuration details for a supported OAuth Flow
|
||||
type OAuthFlowProps struct {
|
||||
// AuthorizationUrl hold the authorization URL to be used for this flow
|
||||
AuthorizationUrl string `json:"authorizationUrl,omitempty"`
|
||||
// TokenUrl holds the token URL to be used for this flow
|
||||
TokenUrl string `json:"tokenUrl,omitempty"`
|
||||
// RefreshUrl holds the URL to be used for obtaining refresh tokens
|
||||
RefreshUrl string `json:"refreshUrl,omitempty"`
|
||||
// Scopes holds the available scopes for the OAuth2 security scheme
|
||||
Scopes map[string]string `json:"scopes,omitempty"`
|
||||
}
|
98
vendor/k8s.io/kube-openapi/pkg/spec3/server.go
generated
vendored
Normal file
98
vendor/k8s.io/kube-openapi/pkg/spec3/server.go
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package spec3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
"github.com/go-openapi/swag"
|
||||
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
ServerProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
type ServerProps struct {
|
||||
// Description is a short description of the target documentation. CommonMark syntax MAY be used for rich text representation.
|
||||
Description string `json:"description,omitempty"`
|
||||
// URL is the URL for the target documentation.
|
||||
URL string `json:"url"`
|
||||
// Variables contains a map between a variable name and its value. The value is used for substitution in the server's URL templeate
|
||||
Variables map[string]*ServerVariable `json:"variables,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode Responses as JSON
|
||||
func (s *Server) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(s.ServerProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(s.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
func (s *Server) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &s.ServerProps); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &s.VendorExtensible); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ServerVariable struct {
|
||||
ServerVariableProps
|
||||
spec.VendorExtensible
|
||||
}
|
||||
|
||||
type ServerVariableProps struct {
|
||||
// Enum is an enumeration of string values to be used if the substitution options are from a limited set
|
||||
Enum []string `json:"enum,omitempty"`
|
||||
// Default is the default value to use for substitution, which SHALL be sent if an alternate value is not supplied
|
||||
Default string `json:"default"`
|
||||
// Description is a description for the server variable
|
||||
Description string `json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON is a custom marshal function that knows how to encode Responses as JSON
|
||||
func (s *ServerVariable) MarshalJSON() ([]byte, error) {
|
||||
b1, err := json.Marshal(s.ServerVariableProps)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b2, err := json.Marshal(s.VendorExtensible)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return swag.ConcatJSON(b1, b2), nil
|
||||
}
|
||||
|
||||
func (s *ServerVariable) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &s.ServerVariableProps); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &s.VendorExtensible); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
37
vendor/k8s.io/kube-openapi/pkg/spec3/spec.go
generated
vendored
Normal file
37
vendor/k8s.io/kube-openapi/pkg/spec3/spec.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright 2021 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package spec3
|
||||
|
||||
import (
|
||||
"k8s.io/kube-openapi/pkg/validation/spec"
|
||||
)
|
||||
|
||||
// OpenAPI is an object that describes an API and conforms to the OpenAPI Specification.
|
||||
type OpenAPI struct {
|
||||
// Version represents the semantic version number of the OpenAPI Specification that this document uses
|
||||
Version string `json:"openapi"`
|
||||
// Info provides metadata about the API
|
||||
Info *spec.Info `json:"info"`
|
||||
// Paths holds the available target and operations for the API
|
||||
Paths *Paths `json:"paths,omitempty"`
|
||||
// Servers is an array of Server objects which provide connectivity information to a target server
|
||||
Servers []*Server `json:"servers,omitempty"`
|
||||
// Components hold various schemas for the specification
|
||||
Components *Components `json:"components,omitempty"`
|
||||
// ExternalDocs holds additional external documentation
|
||||
ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"`
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user