func (g *configRESTOptionsGetter) loadWatchCacheSettings() error { if g.masterOptions.KubernetesMasterConfig == nil { return nil } server := apiserveroptions.NewAPIServer() if errs := cmdflags.Resolve(g.masterOptions.KubernetesMasterConfig.APIServerArguments, server.AddFlags); len(errs) > 0 { return kerrors.NewAggregate(errs) } g.cacheEnabled = server.EnableWatchCache errs := []error{} for _, c := range server.WatchCacheSizes { tokens := strings.Split(c, "#") if len(tokens) != 2 { errs = append(errs, fmt.Errorf("invalid watch cache size value '%s', expecting <resource>#<size> format (e.g. builds#100)", c)) continue } resource := unversioned.ParseGroupResource(tokens[0]) size, err := strconv.Atoi(tokens[1]) if err != nil { errs = append(errs, fmt.Errorf("invalid watch cache size value '%s': %v", c, err)) continue } g.cacheSizes[resource] = size } return kerrors.NewAggregate(errs) }
// ResolveResource returns the resource type and name of the resourceString. // If the resource string has no specified type, defaultResource will be returned. func ResolveResource(defaultResource unversioned.GroupResource, resourceString string, mapper meta.RESTMapper) (unversioned.GroupResource, string, error) { if mapper == nil { return unversioned.GroupResource{}, "", errors.New("mapper cannot be nil") } var name string parts := strings.Split(resourceString, "/") switch len(parts) { case 1: name = parts[0] case 2: name = parts[1] // Allow specifying the group the same way kubectl does, as "resource.group.name" groupResource := unversioned.ParseGroupResource(parts[0]) // normalize resource case groupResource.Resource = strings.ToLower(groupResource.Resource) gvr, err := mapper.ResourceFor(groupResource.WithVersion("")) if err != nil { return unversioned.GroupResource{}, "", err } return gvr.GroupResource(), name, nil default: return unversioned.GroupResource{}, "", fmt.Errorf("invalid resource format: %s", resourceString) } return defaultResource, name, nil }
func (g *configRESTOptionsGetter) loadSettings() error { server := apiserveroptions.NewAPIServer() if g.masterOptions.KubernetesMasterConfig != nil { if errs := cmdflags.Resolve(g.masterOptions.KubernetesMasterConfig.APIServerArguments, server.AddFlags); len(errs) > 0 { return kerrors.NewAggregate(errs) } } storageGroupsToEncodingVersion, err := server.StorageGroupsToEncodingVersion() if err != nil { return err } storageConfig := server.StorageConfig storageConfig.Prefix = g.masterOptions.EtcdStorageConfig.OpenShiftStoragePrefix storageConfig.ServerList = g.masterOptions.EtcdClientInfo.URLs storageConfig.KeyFile = g.masterOptions.EtcdClientInfo.ClientCert.KeyFile storageConfig.CertFile = g.masterOptions.EtcdClientInfo.ClientCert.CertFile storageConfig.CAFile = g.masterOptions.EtcdClientInfo.CA storageFactory, err := genericapiserver.BuildDefaultStorageFactory( storageConfig, server.DefaultStorageMediaType, kapi.Codecs, genericapiserver.NewDefaultResourceEncodingConfig(), storageGroupsToEncodingVersion, nil, g.defaultResourceConfig, server.RuntimeConfig) if err != nil { return err } storageFactory.DefaultResourcePrefixes = g.defaultResourcePrefixes g.storageFactory = storageFactory g.cacheEnabled = server.EnableWatchCache errs := []error{} for _, c := range server.WatchCacheSizes { tokens := strings.Split(c, "#") if len(tokens) != 2 { errs = append(errs, fmt.Errorf("invalid watch cache size value '%s', expecting <resource>#<size> format (e.g. builds#100)", c)) continue } resource := unversioned.ParseGroupResource(tokens[0]) size, err := strconv.Atoi(tokens[1]) if err != nil { errs = append(errs, fmt.Errorf("invalid watch cache size value '%s': %v", c, err)) continue } g.cacheSizes[resource] = size } return kerrors.NewAggregate(errs) }
// RunExplain executes the appropriate steps to print a model's documentation func RunExplain(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error { if len(args) != 1 { return cmdutil.UsageError(cmd, "We accept only this format: explain RESOURCE") } recursive := cmdutil.GetFlagBool(cmd, "recursive") apiVersionString := cmdutil.GetFlagString(cmd, "api-version") apiVersion := unversioned.GroupVersion{} mapper, _ := f.Object() // TODO: After we figured out the new syntax to separate group and resource, allow // the users to use it in explain (kubectl explain <group><syntax><resource>). // Refer to issue #16039 for why we do this. Refer to PR #15808 that used "/" syntax. inModel, fieldsPath, err := kubectl.SplitAndParseResourceRequest(args[0], mapper) if err != nil { return err } // TODO: We should deduce the group for a resource by discovering the supported resources at server. gvk, err := mapper.KindFor(unversioned.ParseGroupResource(inModel).WithVersion("")) if err != nil { return err } if len(apiVersionString) == 0 { groupMeta, err := registered.Group(gvk.Group) if err != nil { return err } apiVersion = groupMeta.GroupVersion } else { apiVersion, err = unversioned.ParseGroupVersion(apiVersionString) if err != nil { return nil } } schema, err := f.SwaggerSchema(apiVersion.WithKind(gvk.Kind)) if err != nil { return err } return kubectl.PrintModelDescription(inModel, fieldsPath, out, schema, recursive) }
func (b *Builder) resourceMappings() ([]*meta.RESTMapping, error) { if len(b.resources) > 1 && b.singleResourceType { return nil, fmt.Errorf("you may only specify a single resource type") } mappings := []*meta.RESTMapping{} for _, r := range b.resources { gvk, err := b.mapper.KindFor(unversioned.ParseGroupResource(r).WithVersion("")) if err != nil { return nil, err } mapping, err := b.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) if err != nil { return nil, err } mappings = append(mappings, mapping) } return mappings, nil }
func (b *Builder) resourceTupleMappings() (map[string]*meta.RESTMapping, error) { mappings := make(map[string]*meta.RESTMapping) canonical := make(map[string]struct{}) for _, r := range b.resourceTuples { if _, ok := mappings[r.Resource]; ok { continue } gvk, err := b.mapper.KindFor(unversioned.ParseGroupResource(r.Resource).WithVersion("")) if err != nil { return nil, err } mapping, err := b.mapper.RESTMapping(gvk.GroupKind(), gvk.Version) if err != nil { return nil, err } mappings[mapping.Resource] = mapping mappings[r.Resource] = mapping canonical[mapping.Resource] = struct{}{} } if len(canonical) > 1 && b.singleResourceType { return nil, fmt.Errorf("you may only specify a single resource type") } return mappings, nil }
func (o *ObserveOptions) Complete(f *clientcmd.Factory, cmd *cobra.Command, args []string, out, errOut io.Writer) error { var err error var command []string if i := cmd.ArgsLenAtDash(); i != -1 { command = args[i:] args = args[:i] } o.eachCommand = command switch len(args) { case 0: return fmt.Errorf("you must specify at least one argument containing the resource to observe") case 1: default: return fmt.Errorf("you may only specify one argument containing the resource to observe (use '--' to separate your resource and your command)") } gr := unversioned.ParseGroupResource(args[0]) if gr.Empty() { return fmt.Errorf("unknown resource argument") } mapper, _ := f.Object(true) version, err := mapper.KindFor(gr.WithVersion("")) if err != nil { return err } mapping, err := mapper.RESTMapping(version.GroupKind()) if err != nil { return err } o.mapping = mapping o.includeNamespace = mapping.Scope.Name() == meta.RESTScopeNamespace.Name() client, err := f.ClientForMapping(mapping) if err != nil { return err } o.client = client o.namespace, _, err = f.DefaultNamespace() if err != nil { return err } switch o.templateType { case "jsonpath": p, err := NewJSONPathArgumentPrinter(o.includeNamespace, o.strictTemplates, o.templates...) if err != nil { return err } o.printer = p case "gotemplate": p, err := NewGoTemplateArgumentPrinter(o.includeNamespace, o.strictTemplates, o.templates...) if err != nil { return err } o.printer = p default: return fmt.Errorf("template type %q not recognized - valid values are jsonpath and gotemplate", o.templateType) } o.printer = NewVersionedColumnPrinter(o.printer, o.mapping.ObjectConvertor, version.GroupVersion()) o.out, o.errOut = out, errOut if o.noHeaders { o.debugOut = ioutil.Discard } else { o.debugOut = out } o.argumentStore = &objectArgumentsStore{} switch { case len(o.nameSyncCommand) > 0: o.argumentStore.keyFn = func() ([]string, error) { var out []byte err := retryCommandError(o.retryExitStatus, o.retryCount, func() error { c := exec.Command(o.nameSyncCommand[0], o.nameSyncCommand[1:]...) var err error return measureCommandDuration(nameExecDurations, func() error { out, err = c.Output() return err }) }) if err != nil { if exit, ok := err.(*exec.ExitError); ok { if len(exit.Stderr) > 0 { err = fmt.Errorf("%v\n%s", err, string(exit.Stderr)) } } return nil, err } names := strings.Split(string(out), "\n") sort.Sort(sort.StringSlice(names)) var outputNames []string for i, s := range names { if len(s) != 0 { outputNames = names[i:] break } } glog.V(4).Infof("Found existing keys: %v", outputNames) return outputNames, nil } o.knownObjects = o.argumentStore case len(o.deleteCommand) > 0: o.knownObjects = o.argumentStore } return nil }