// buildPaths builds OpenAPI paths using go-restful's web services. func (o *openAPI) buildPaths(webServices []*restful.WebService) error { pathsToIgnore := util.CreateTrie(o.config.IgnorePrefixes) duplicateOpId := make(map[string]string) 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.swagger.Paths.Paths[path] if exists { return fmt.Errorf("duplicate webservice route has been found for path: %v", path) } pathItem = spec.PathItem{ PathItemProps: spec.PathItemProps{ Parameters: make([]spec.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, err := o.buildOperations(route, inPathCommonParamsMap) sortParameters(op.Parameters) if err != nil { return err } dpath, exists := duplicateOpId[op.ID] if exists { return fmt.Errorf("Duplicate Operation ID %v for path %v and %v.", op.ID, dpath, path) } else { duplicateOpId[op.ID] = path } 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.swagger.Paths.Paths[path] = pathItem } } return nil }
*/ package openapi import ( "bytes" "fmt" "strings" "unicode" "github.com/emicklei/go-restful" "k8s.io/kubernetes/pkg/util" ) var verbs = util.CreateTrie([]string{"get", "log", "read", "replace", "patch", "delete", "deletecollection", "watch", "connect", "proxy", "list", "create", "patch"}) // ToValidOperationID makes an string a valid op ID (e.g. removing punctuations and whitespaces and make it camel case) func ToValidOperationID(s string, capitalizeFirstLetter bool) string { var buffer bytes.Buffer capitalize := capitalizeFirstLetter for i, r := range s { if unicode.IsLetter(r) || r == '_' || (i != 0 && unicode.IsDigit(r)) { if capitalize { buffer.WriteRune(unicode.ToUpper(r)) capitalize = false } else { buffer.WriteRune(r) } } else { capitalize = true