func newExternalScheme() (*runtime.Scheme, meta.RESTMapper, runtime.Codec) { scheme := runtime.NewScheme() scheme.AddKnownTypeWithName("", "Type", &internalType{}) scheme.AddKnownTypeWithName("unlikelyversion", "Type", &externalType{}) //This tests that qingctl will not confuse the external scheme with the internal scheme, even when they accidentally have versions of the same name. scheme.AddKnownTypeWithName(testapi.Version(), "Type", &ExternalType2{}) codec := runtime.CodecFor(scheme, "unlikelyversion") validVersion := testapi.Version() mapper := meta.NewDefaultRESTMapper([]string{"unlikelyversion", validVersion}, func(version string) (*meta.VersionInterfaces, bool) { return &meta.VersionInterfaces{ Codec: runtime.CodecFor(scheme, version), ObjectConvertor: scheme, MetadataAccessor: meta.NewAccessor(), }, (version == validVersion || version == "unlikelyversion") }) for _, version := range []string{"unlikelyversion", validVersion} { for kind := range scheme.KnownTypes(version) { mixedCase := false scope := meta.RESTScopeNamespace mapper.Add(scope, kind, version, mixedCase) } } return scheme, mapper, codec }
// Admit admits resources into cluster that do not violate any defined LimitRange in the namespace func (l *limitRanger) Admit(a admission.Attributes) (err error) { // Ignore all calls to subresources if a.GetSubresource() != "" { return nil } obj := a.GetObject() resource := a.GetResource() name := "Unknown" if obj != nil { name, _ = meta.NewAccessor().Name(obj) if len(name) == 0 { name, _ = meta.NewAccessor().GenerateName(obj) } } key := &api.LimitRange{ ObjectMeta: api.ObjectMeta{ Namespace: a.GetNamespace(), Name: "", }, } items, err := l.indexer.Index("namespace", key) if err != nil { return admission.NewForbidden(a, fmt.Errorf("Unable to %s %s at this time because there was an error enforcing limit ranges", a.GetOperation(), resource)) } if len(items) == 0 { return nil } // ensure it meets each prescribed min/max for i := range items { limitRange := items[i].(*api.LimitRange) err = l.limitFunc(limitRange, a.GetResource(), a.GetObject()) if err != nil { return admission.NewForbidden(a, err) } } return nil }
// NewFactory creates a factory with the default QingYuan resources defined // if optionalClientConfig is nil, then flags will be bound to a new clientcmd.ClientConfig. // if optionalClientConfig is not nil, then this factory will make use of it. func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory { mapper := qingctl.ShortcutExpander{latest.RESTMapper} flags := pflag.NewFlagSet("", pflag.ContinueOnError) flags.SetNormalizeFunc(util.WarnWordSepNormalizeFunc) // Warn for "_" flags generators := map[string]qingctl.Generator{ "run/v1": qingctl.BasicReplicationController{}, "service/v1": qingctl.ServiceGenerator{}, } clientConfig := optionalClientConfig if optionalClientConfig == nil { clientConfig = DefaultClientConfig(flags) } clients := NewClientCache(clientConfig) return &Factory{ clients: clients, flags: flags, generators: generators, Object: func() (meta.RESTMapper, runtime.ObjectTyper) { cfg, err := clientConfig.ClientConfig() CheckErr(err) cmdApiVersion := cfg.Version return qingctl.OutputVersionMapper{mapper, cmdApiVersion}, api.Scheme }, Client: func() (*client.Client, error) { return clients.ClientForVersion("") }, ClientConfig: func() (*client.Config, error) { return clients.ClientConfigForVersion("") }, RESTClient: func(mapping *meta.RESTMapping) (resource.RESTClient, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } return client.RESTClient, nil }, Describer: func(mapping *meta.RESTMapping) (qingctl.Describer, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } describer, ok := qingctl.DescriberFor(mapping.Kind, client) if !ok { return nil, fmt.Errorf("no description has been implemented for %q", mapping.Kind) } return describer, nil }, Printer: func(mapping *meta.RESTMapping, noHeaders, withNamespace bool, columnLabels []string) (qingctl.ResourcePrinter, error) { return qingctl.NewHumanReadablePrinter(noHeaders, withNamespace, columnLabels), nil }, PodSelectorForObject: func(object runtime.Object) (string, error) { // TODO: replace with a swagger schema based approach (identify pod selector via schema introspection) switch t := object.(type) { case *api.ReplicationController: return qingctl.MakeLabels(t.Spec.Selector), nil case *api.Pod: if len(t.Labels) == 0 { return "", fmt.Errorf("the pod has no labels and cannot be exposed") } return qingctl.MakeLabels(t.Labels), nil case *api.Service: if t.Spec.Selector == nil { return "", fmt.Errorf("the service has no pod selector set") } return qingctl.MakeLabels(t.Spec.Selector), nil default: kind, err := meta.NewAccessor().Kind(object) if err != nil { return "", err } return "", fmt.Errorf("it is not possible to get a pod selector from %s", kind) } }, PortsForObject: func(object runtime.Object) ([]string, error) { // TODO: replace with a swagger schema based approach (identify pod selector via schema introspection) switch t := object.(type) { case *api.ReplicationController: return getPorts(t.Spec.Template.Spec), nil case *api.Pod: return getPorts(t.Spec), nil default: kind, err := meta.NewAccessor().Kind(object) if err != nil { return nil, err } return nil, fmt.Errorf("it is not possible to get ports from %s", kind) } }, LabelsForObject: func(object runtime.Object) (map[string]string, error) { return meta.NewAccessor().Labels(object) }, Scaler: func(mapping *meta.RESTMapping) (qingctl.Scaler, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } return qingctl.ScalerFor(mapping.Kind, qingctl.NewScalerClient(client)) }, Reaper: func(mapping *meta.RESTMapping) (qingctl.Reaper, error) { client, err := clients.ClientForVersion(mapping.APIVersion) if err != nil { return nil, err } return qingctl.ReaperFor(mapping.Kind, client) }, Validator: func() (validation.Schema, error) { if flags.Lookup("validate").Value.String() == "true" { client, err := clients.ClientForVersion("") if err != nil { return nil, err } return &clientSwaggerSchema{client, api.Scheme}, nil } return validation.NullSchema{}, nil }, DefaultNamespace: func() (string, error) { return clientConfig.Namespace() }, Generator: func(name string) (qingctl.Generator, bool) { generator, ok := generators[name] return generator, ok }, } }