func (m *DefaultRESTMapper) KindFor(resource unversioned.GroupVersionResource) (unversioned.GroupVersionKind, error) { kinds, err := m.KindsFor(resource) if err != nil { return unversioned.GroupVersionKind{}, err } // TODO for each group, choose the most preferred (first) version. This keeps us consistent with code today. // eventually, we'll need a RESTMapper that is aware of what's available server-side and deconflicts that with // user preferences oneKindPerGroup := []unversioned.GroupVersionKind{} groupsAdded := sets.String{} for _, kind := range kinds { if groupsAdded.Has(kind.Group) { continue } oneKindPerGroup = append(oneKindPerGroup, kind) groupsAdded.Insert(kind.Group) } if len(oneKindPerGroup) == 1 { return oneKindPerGroup[0], nil } return unversioned.GroupVersionKind{}, fmt.Errorf("%v is ambiguous, got: %v", resource, kinds) }
func (g *conversionGenerator) RepackImports(exclude sets.String) { var packages []string for key := range g.imports { packages = append(packages, key) } sort.Strings(packages) g.imports = make(map[string]string) g.shortImports = make(map[string]string) g.targetPackage(g.targetPkg) for _, pkg := range packages { if !exclude.Has(pkg) { g.addImportByPath(pkg) } } }
func ValidateThirdPartyResource(obj *extensions.ThirdPartyResource) field.ErrorList { allErrs := field.ErrorList{} allErrs = append(allErrs, apivalidation.ValidateObjectMeta(&obj.ObjectMeta, true, ValidateThirdPartyResourceName, field.NewPath("metadata"))...) versions := sets.String{} for ix := range obj.Versions { version := &obj.Versions[ix] if len(version.Name) == 0 { allErrs = append(allErrs, field.Invalid(field.NewPath("versions").Index(ix).Child("name"), version, "must not be empty")) } if versions.Has(version.Name) { allErrs = append(allErrs, field.Duplicate(field.NewPath("versions").Index(ix).Child("name"), version)) } versions.Insert(version.Name) } return allErrs }
func NewDefaultRESTMapper(defaultGroupVersions []unversioned.GroupVersion, interfacesFunc meta.VersionInterfacesFunc, importPathPrefix string, ignoredKinds, rootScoped sets.String) *meta.DefaultRESTMapper { mapper := meta.NewDefaultRESTMapper(defaultGroupVersions, interfacesFunc) // enumerate all supported versions, get the kinds, and register with the mapper how to address // our resources. for _, gv := range defaultGroupVersions { for kind, oType := range Scheme.KnownTypes(gv) { gvk := gv.WithKind(kind) // TODO: Remove import path prefix check. // We check the import path prefix because we currently stuff both "api" and "extensions" objects // into the same group within Scheme since Scheme has no notion of groups yet. if !strings.HasPrefix(oType.PkgPath(), importPathPrefix) || ignoredKinds.Has(kind) { continue } scope := meta.RESTScopeNamespace if rootScoped.Has(kind) { scope = meta.RESTScopeRoot } mapper.Add(gvk, scope, false) } } return mapper }
// NegotiateVersion queries the server's supported api versions to find // a version that both client and server support. // - If no version is provided, try registered client versions in order of // preference. // - If version is provided, but not default config (explicitly requested via // commandline flag), and is unsupported by the server, print a warning to // stderr and try client's registered versions in order of preference. // - If version is config default, and the server does not support it, // return an error. func NegotiateVersion(client *Client, c *Config, requestedGV *unversioned.GroupVersion, clientRegisteredGVs []unversioned.GroupVersion) (*unversioned.GroupVersion, error) { var err error if client == nil { client, err = New(c) if err != nil { return nil, err } } clientVersions := sets.String{} for _, gv := range clientRegisteredGVs { clientVersions.Insert(gv.String()) } groups, err := client.ServerGroups() if err != nil { // This is almost always a connection error, and higher level code should treat this as a generic error, // not a negotiation specific error. return nil, err } versions := ExtractGroupVersions(groups) serverVersions := sets.String{} for _, v := range versions { serverVersions.Insert(v) } // If no version requested, use config version (may also be empty). // make a copy of the original so we don't risk mutating input here or in the returned value var preferredGV *unversioned.GroupVersion switch { case requestedGV != nil: t := *requestedGV preferredGV = &t case c.GroupVersion != nil: t := *c.GroupVersion preferredGV = &t } // If version explicitly requested verify that both client and server support it. // If server does not support warn, but try to negotiate a lower version. if preferredGV != nil { if !clientVersions.Has(preferredGV.String()) { return nil, fmt.Errorf("client does not support API version %q; client supported API versions: %v", preferredGV, clientVersions) } if serverVersions.Has(preferredGV.String()) { return preferredGV, nil } // If we are using an explicit config version the server does not support, fail. if (c.GroupVersion != nil) && (*preferredGV == *c.GroupVersion) { return nil, fmt.Errorf("server does not support API version %q", preferredGV) } } for _, clientGV := range clientRegisteredGVs { if serverVersions.Has(clientGV.String()) { // Version was not explicitly requested in command config (--api-version). // Ok to fall back to a supported version with a warning. // TODO: caesarxuchao: enable the warning message when we have // proper fix. Please refer to issue #14895. // if len(version) != 0 { // glog.Warningf("Server does not support API version '%s'. Falling back to '%s'.", version, clientVersion) // } t := clientGV return &t, nil } } return nil, fmt.Errorf("failed to negotiate an api version; server supports: %v, client supports: %v", serverVersions, clientVersions) }