mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-05 07:27:21 +00:00
kubectl: Remove swagger 1.2 entirely.
This commit is contained in:
@@ -17,20 +17,13 @@ limitations under the License.
|
||||
package util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/user"
|
||||
"path"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
swagger "github.com/emicklei/go-restful-swagger12"
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
@@ -39,7 +32,6 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/discovery"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
@@ -233,8 +225,6 @@ type ObjectMappingFactory interface {
|
||||
|
||||
// Returns a schema that can validate objects stored on disk.
|
||||
Validator(validate bool) (validation.Schema, error)
|
||||
// SwaggerSchema returns the schema declaration for the provided group version kind.
|
||||
SwaggerSchema(schema.GroupVersionKind) (*swagger.ApiDeclaration, error)
|
||||
// OpenAPISchema returns the schema openapi schema definiton
|
||||
OpenAPISchema() (openapi.Resources, error)
|
||||
}
|
||||
@@ -389,145 +379,3 @@ func getServiceProtocols(spec api.ServiceSpec) map[string]string {
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
type clientSwaggerSchema struct {
|
||||
c restclient.Interface
|
||||
cacheDir string
|
||||
}
|
||||
|
||||
const schemaFileName = "schema.json"
|
||||
|
||||
type schemaClient interface {
|
||||
Get() *restclient.Request
|
||||
}
|
||||
|
||||
func recursiveSplit(dir string) []string {
|
||||
parent, file := path.Split(dir)
|
||||
if len(parent) == 0 {
|
||||
return []string{file}
|
||||
}
|
||||
return append(recursiveSplit(parent[:len(parent)-1]), file)
|
||||
}
|
||||
|
||||
func substituteUserHome(dir string) (string, error) {
|
||||
if len(dir) == 0 || dir[0] != '~' {
|
||||
return dir, nil
|
||||
}
|
||||
parts := recursiveSplit(dir)
|
||||
if len(parts[0]) == 1 {
|
||||
parts[0] = os.Getenv("HOME")
|
||||
} else {
|
||||
usr, err := user.Lookup(parts[0][1:])
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
parts[0] = usr.HomeDir
|
||||
}
|
||||
return path.Join(parts...), nil
|
||||
}
|
||||
|
||||
func writeSchemaFile(schemaData []byte, cacheDir, cacheFile, prefix, groupVersion string) error {
|
||||
if err := os.MkdirAll(path.Join(cacheDir, prefix, groupVersion), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
tmpFile, err := ioutil.TempFile(cacheDir, "schema")
|
||||
if err != nil {
|
||||
// If we can't write, keep going.
|
||||
if os.IsPermission(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(tmpFile, bytes.NewBuffer(schemaData)); err != nil {
|
||||
return err
|
||||
}
|
||||
glog.V(4).Infof("Writing swagger cache (dir %v) file %v (from %v)", cacheDir, cacheFile, tmpFile.Name())
|
||||
if err := os.Link(tmpFile.Name(), cacheFile); err != nil {
|
||||
// If we can't write due to file existing, or permission problems, keep going.
|
||||
if os.IsExist(err) || os.IsPermission(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getSchemaAndValidate(c schemaClient, data []byte, prefix, groupVersion, cacheDir string, delegate validation.Schema) (err error) {
|
||||
var schemaData []byte
|
||||
var firstSeen bool
|
||||
fullDir, err := substituteUserHome(cacheDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cacheFile := path.Join(fullDir, prefix, groupVersion, schemaFileName)
|
||||
|
||||
if len(cacheDir) != 0 {
|
||||
if schemaData, err = ioutil.ReadFile(cacheFile); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if schemaData == nil {
|
||||
firstSeen = true
|
||||
schemaData, err = downloadSchemaAndStore(c, cacheDir, fullDir, cacheFile, prefix, groupVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
schema, err := validation.NewSwaggerSchemaFromBytes(schemaData, delegate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = schema.ValidateBytes(data)
|
||||
if _, ok := err.(validation.TypeNotFoundError); ok && !firstSeen {
|
||||
// As a temporary hack, kubectl would re-get the schema if validation
|
||||
// fails for type not found reason.
|
||||
// TODO: runtime-config settings needs to make into the file's name
|
||||
schemaData, err = downloadSchemaAndStore(c, cacheDir, fullDir, cacheFile, prefix, groupVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
schema, err := validation.NewSwaggerSchemaFromBytes(schemaData, delegate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return schema.ValidateBytes(data)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Download swagger schema from apiserver and store it to file.
|
||||
func downloadSchemaAndStore(c schemaClient, cacheDir, fullDir, cacheFile, prefix, groupVersion string) (schemaData []byte, err error) {
|
||||
schemaData, err = c.Get().
|
||||
AbsPath("/swaggerapi", prefix, groupVersion).
|
||||
Do().
|
||||
Raw()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if len(cacheDir) != 0 {
|
||||
if err = writeSchemaFile(schemaData, fullDir, cacheFile, prefix, groupVersion); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *clientSwaggerSchema) ValidateBytes(data []byte) error {
|
||||
gvk, err := json.DefaultMetaFactory.Interpret(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ok := api.Registry.IsEnabledVersion(gvk.GroupVersion()); !ok {
|
||||
// if we don't have this in our scheme, just skip validation because its an object we don't recognize
|
||||
return nil
|
||||
}
|
||||
|
||||
switch gvk.Group {
|
||||
case api.GroupName:
|
||||
return getSchemaAndValidate(c.c, data, "api", gvk.GroupVersion().String(), c.cacheDir, c)
|
||||
|
||||
default:
|
||||
return getSchemaAndValidate(c.c, data, "apis/", gvk.GroupVersion().String(), c.cacheDir, c)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user