diff --git a/go.mod b/go.mod index 5f51cba..7a8e22b 100644 --- a/go.mod +++ b/go.mod @@ -4,12 +4,11 @@ go 1.20 require ( github.com/fatih/structtag v1.2.0 - github.com/getkin/kin-openapi v0.123.0 - github.com/goccy/go-json v0.10.0 - github.com/invopop/yaml v0.2.0 + github.com/getkin/kin-openapi v0.124.0 + github.com/goccy/go-json v0.10.2 + github.com/invopop/yaml v0.3.1 github.com/pubgo/funk v0.5.41 - github.com/stretchr/testify v1.8.4 - k8s.io/kube-openapi v0.0.0-20221123214604-86e75ddd809a + github.com/stretchr/testify v1.9.0 ) require ( diff --git a/go.sum b/go.sum index 15e6f52..3eb1f37 100644 --- a/go.sum +++ b/go.sum @@ -5,21 +5,21 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= -github.com/getkin/kin-openapi v0.123.0 h1:zIik0mRwFNLyvtXK274Q6ut+dPh6nlxBp0x7mNrPhs8= -github.com/getkin/kin-openapi v0.123.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM= +github.com/getkin/kin-openapi v0.124.0 h1:VSFNMB9C9rTKBnQ/fpyDU8ytMTr4dWI9QovSKj9kz/M= +github.com/getkin/kin-openapi v0.124.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM= github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= github.com/go-openapi/swag v0.22.8 h1:/9RjDSQ0vbFR+NyjGMkFTsA1IA0fmhKSThmfGZjicbw= github.com/go-openapi/swag v0.22.8/go.mod h1:6QT22icPLEqAM/z/TChgb4WAveCHF92+2gF0CNjHpPI= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= -github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA= -github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY= -github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= +github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= +github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/k0kubun/pp/v3 v3.2.0 h1:h33hNTZ9nVFNP3u2Fsgz8JXiF5JINoZfFq4SvKJwNcs= @@ -51,8 +51,8 @@ github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w= github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= golang.org/x/exp v0.0.0-20221114191408-850992195362 h1:NoHlPRbyl1VFI6FjwHtPQCN7wAMXI6cKcqrmXhOOfBQ= golang.org/x/exp v0.0.0-20221114191408-850992195362/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= @@ -72,8 +72,5 @@ google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGm google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/kube-openapi v0.0.0-20221123214604-86e75ddd809a h1:UR2YSPKAb8j3uL2yK8V+t2ElG4RoBxhJTxa5gg0ZtSo= -k8s.io/kube-openapi v0.0.0-20221123214604-86e75ddd809a/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= diff --git a/opendoc/swagger_test.go b/opendoc/swagger_test.go index 71e8021..ef07567 100644 --- a/opendoc/swagger_test.go +++ b/opendoc/swagger_test.go @@ -6,17 +6,16 @@ import ( "github.com/getkin/kin-openapi/openapi3" "github.com/goccy/go-json" "github.com/stretchr/testify/assert" - "k8s.io/kube-openapi/pkg/util" ) func TestRefName(t *testing.T) { assert.Equal(t, "com.github.getkin.kin-openapi.openapi3.License", - util.ToRESTFriendlyName(util.GetCanonicalTypeName(new(openapi3.License)))) + ToRESTFriendlyName(GetCanonicalTypeName(new(openapi3.License)))) assert.Equal(t, "github.com/getkin/kin-openapi/openapi3.License", - util.GetCanonicalTypeName(new(openapi3.License))) + GetCanonicalTypeName(new(openapi3.License))) } type testQueryRsp struct { diff --git a/opendoc/util.go b/opendoc/util.go index 876a8cc..9889945 100644 --- a/opendoc/util.go +++ b/opendoc/util.go @@ -16,7 +16,6 @@ import ( "github.com/pubgo/funk/assert" "github.com/pubgo/funk/log" "github.com/pubgo/opendoc/security" - "k8s.io/kube-openapi/pkg/util" ) func getTag(tags *structtag.Tags, key string, fn func(tag *structtag.Tag)) { @@ -42,14 +41,14 @@ func checkModelType(model interface{}) { } func getSchemaName(val interface{}) string { - return util.ToRESTFriendlyName(getCanonicalTypeName(val)) + return ToRESTFriendlyName(GetCanonicalTypeName(val)) } func getComponentName(name string) string { return fmt.Sprintf("#/components/schemas/%s", name) } -func getCanonicalTypeName(val interface{}) string { +func GetCanonicalTypeName(val interface{}) string { var model reflect.Type if typ, ok := val.(reflect.Type); ok { model = typ @@ -101,19 +100,19 @@ func genSchema(val interface{}) (ref string, schema *openapi3.Schema) { case reflect.TypeOf([]byte{}): return "", openapi3.NewBytesSchema() case reflect.TypeOf(multipart.FileHeader{}): - return "", &openapi3.Schema{Type: openapi3.TypeString, Format: "binary"} + return "", &openapi3.Schema{Type: &openapi3.Types{openapi3.TypeString}, Format: "binary"} case reflect.TypeOf([]*multipart.FileHeader{}): schema = openapi3.NewArraySchema() - schema.Items = openapi3.NewSchemaRef("", &openapi3.Schema{Type: openapi3.TypeString, Format: "binary"}) + schema.Items = openapi3.NewSchemaRef("", &openapi3.Schema{Type: &openapi3.Types{openapi3.TypeString}, Format: "binary"}) return "", schema case reflect.TypeOf(time.Time{}): return "", openapi3.NewDateTimeSchema() case reflect.TypeOf(time.Duration(0)): - return "", &openapi3.Schema{Type: openapi3.TypeString, Format: "duration"} + return "", &openapi3.Schema{Type: &openapi3.Types{openapi3.TypeString}, Format: "duration"} case reflect.TypeOf(net.IP{}): - return "", &openapi3.Schema{Type: openapi3.TypeString, Format: "ipv4"} + return "", &openapi3.Schema{Type: &openapi3.Types{openapi3.TypeString}, Format: "ipv4"} case reflect.TypeOf(url.URL{}): - return "", &openapi3.Schema{Type: openapi3.TypeString, Format: "uri"} + return "", &openapi3.Schema{Type: &openapi3.Types{openapi3.TypeString}, Format: "uri"} } switch v := val.(type) { @@ -398,3 +397,30 @@ func Escape(token string) string { step2 := strings.ReplaceAll(step1, decRefTok1, encRefTok1) return step2 } + +// ToRESTFriendlyName converts Golang package/type canonical name into REST friendly OpenAPI name. +// +// Examples of REST friendly OpenAPI name: +// +// Input: k8s.io/api/core/v1.Pod +// Output: io.k8s.api.core.v1.Pod +// +// Input: k8s.io/api/core/v1 +// Output: io.k8s.api.core.v1 +// +// Input: csi.storage.k8s.io/v1alpha1.CSINodeInfo +// Output: io.k8s.storage.csi.v1alpha1.CSINodeInfo +// +// Copy from k8s.io/kube-openapi +func ToRESTFriendlyName(name string) string { + nameParts := strings.Split(name, "/") + // Reverse first part. e.g., io.k8s... instead of k8s.io... + if len(nameParts) > 0 && strings.Contains(nameParts[0], ".") { + parts := strings.Split(nameParts[0], ".") + for i, j := 0, len(parts)-1; i < j; i, j = i+1, j-1 { + parts[i], parts[j] = parts[j], parts[i] + } + nameParts[0] = strings.Join(parts, ".") + } + return strings.Join(nameParts, ".") +}