func newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper { // the list of kinds that are scoped at the root of the api hierarchy // if a kind is not enumerated here, it is assumed to have a namespace scope rootScoped := sets.NewString( "Node", "Namespace", "PersistentVolume", "ComponentStatus", ) // these kinds should be excluded from the list of resources ignoredKinds := sets.NewString( "ListOptions", "DeleteOptions", "Status", "PodLogOptions", "PodExecOptions", "PodAttachOptions", "PodProxyOptions", "NodeProxyOptions", "ServiceProxyOptions", "ThirdPartyResource", "ThirdPartyResourceData", "ThirdPartyResourceList") mapper := api.NewDefaultRESTMapper(externalVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) return mapper }
// Test public interface func doTestIndex(t *testing.T, indexer Indexer) { mkObj := func(id string, val string) testStoreObject { return testStoreObject{id: id, val: val} } // Test Index expected := map[string]sets.String{} expected["b"] = sets.NewString("a", "c") expected["f"] = sets.NewString("e") expected["h"] = sets.NewString("g") indexer.Add(mkObj("a", "b")) indexer.Add(mkObj("c", "b")) indexer.Add(mkObj("e", "f")) indexer.Add(mkObj("g", "h")) { for k, v := range expected { found := sets.String{} indexResults, err := indexer.Index("by_val", mkObj("", k)) if err != nil { t.Errorf("Unexpected error %v", err) } for _, item := range indexResults { found.Insert(item.(testStoreObject).id) } items := v.List() if !found.HasAll(items...) { t.Errorf("missing items, index %s, expected %v but found %v", k, items, found.List()) } } } }
func newRESTMapper(externalVersions []unversioned.GroupVersion) meta.RESTMapper { // the list of kinds that are scoped at the root of the api hierarchy // if a kind is not enumerated here, it is assumed to have a namespace scope rootScoped := sets.NewString( "Cluster", ) ignoredKinds := sets.NewString() return api.NewDefaultRESTMapper(externalVersions, interfacesFor, importPrefix, ignoredKinds, rootScoped) }
func TestReAddExpiredItem(t *testing.T) { deleteChan := make(chan string, 1) exp := &FakeExpirationPolicy{ NeverExpire: sets.NewString(), RetrieveKeyFunc: func(obj interface{}) (string, error) { return obj.(*timestampedEntry).obj.(testStoreObject).id, nil }, } ttlStore := NewFakeExpirationStore( testStoreKeyFunc, deleteChan, exp, clock.RealClock{}) testKey := "foo" testObj := testStoreObject{id: testKey, val: "bar"} err := ttlStore.Add(testObj) if err != nil { t.Errorf("Unable to add obj %#v", testObj) } // This get will expire the item. item, exists, err := ttlStore.Get(testObj) if err != nil { t.Errorf("Failed to get from store, %v", err) } if exists || item != nil { t.Errorf("Got unexpected item %#v", item) } key, _ := testStoreKeyFunc(testObj) differentValue := "different_bar" err = ttlStore.Add( testStoreObject{id: testKey, val: differentValue}) if err != nil { t.Errorf("Failed to add second value") } select { case delKey := <-deleteChan: if delKey != key { t.Errorf("Unexpected delete for key %s", key) } case <-time.After(wait.ForeverTestTimeout): t.Errorf("Unexpected timeout waiting on delete") } exp.NeverExpire = sets.NewString(testKey) item, exists, err = ttlStore.GetByKey(testKey) if err != nil { t.Errorf("Failed to get from store, %v", err) } if !exists || item == nil || item.(testStoreObject).val != differentValue { t.Errorf("Got unexpected item %#v", item) } close(deleteChan) }
// RESTMapper returns a union RESTMapper of all known types with priorities chosen in the following order: // 1. if KUBE_API_VERSIONS is specified, then KUBE_API_VERSIONS in order, OR // 1. legacy kube group preferred version, extensions preferred version, metrics perferred version, legacy // kube any version, extensions any version, metrics any version, all other groups alphabetical preferred version, // all other groups alphabetical. func (m *APIRegistrationManager) RESTMapper(versionPatterns ...unversioned.GroupVersion) meta.RESTMapper { unionMapper := meta.MultiRESTMapper{} unionedGroups := sets.NewString() for enabledVersion := range m.enabledVersions { if !unionedGroups.Has(enabledVersion.Group) { unionedGroups.Insert(enabledVersion.Group) groupMeta := m.groupMetaMap[enabledVersion.Group] unionMapper = append(unionMapper, groupMeta.RESTMapper) } } if len(versionPatterns) != 0 { resourcePriority := []unversioned.GroupVersionResource{} kindPriority := []unversioned.GroupVersionKind{} for _, versionPriority := range versionPatterns { resourcePriority = append(resourcePriority, versionPriority.WithResource(meta.AnyResource)) kindPriority = append(kindPriority, versionPriority.WithKind(meta.AnyKind)) } return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority} } if len(m.envRequestedVersions) != 0 { resourcePriority := []unversioned.GroupVersionResource{} kindPriority := []unversioned.GroupVersionKind{} for _, versionPriority := range m.envRequestedVersions { resourcePriority = append(resourcePriority, versionPriority.WithResource(meta.AnyResource)) kindPriority = append(kindPriority, versionPriority.WithKind(meta.AnyKind)) } return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority} } prioritizedGroups := []string{"", "extensions", "metrics"} resourcePriority, kindPriority := m.prioritiesForGroups(prioritizedGroups...) prioritizedGroupsSet := sets.NewString(prioritizedGroups...) remainingGroups := sets.String{} for enabledVersion := range m.enabledVersions { if !prioritizedGroupsSet.Has(enabledVersion.Group) { remainingGroups.Insert(enabledVersion.Group) } } remainingResourcePriority, remainingKindPriority := m.prioritiesForGroups(remainingGroups.List()...) resourcePriority = append(resourcePriority, remainingResourcePriority...) kindPriority = append(kindPriority, remainingKindPriority...) return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority} }
// NodeSelectorRequirementsAsSelector converts the []NodeSelectorRequirement api type into a struct that implements // labels.Selector. func NodeSelectorRequirementsAsSelector(nsm []NodeSelectorRequirement) (labels.Selector, error) { if len(nsm) == 0 { return labels.Nothing(), nil } selector := labels.NewSelector() for _, expr := range nsm { var op selection.Operator switch expr.Operator { case NodeSelectorOpIn: op = selection.In case NodeSelectorOpNotIn: op = selection.NotIn case NodeSelectorOpExists: op = selection.Exists case NodeSelectorOpDoesNotExist: op = selection.DoesNotExist case NodeSelectorOpGt: op = selection.GreaterThan case NodeSelectorOpLt: op = selection.LessThan default: return nil, fmt.Errorf("%q is not a valid node selector operator", expr.Operator) } r, err := labels.NewRequirement(expr.Key, op, sets.NewString(expr.Values...)) if err != nil { return nil, err } selector = selector.Add(*r) } return selector, nil }
func TestTTLExpirationBasic(t *testing.T) { testObj := testStoreObject{id: "foo", val: "bar"} deleteChan := make(chan string, 1) ttlStore := NewFakeExpirationStore( testStoreKeyFunc, deleteChan, &FakeExpirationPolicy{ NeverExpire: sets.NewString(), RetrieveKeyFunc: func(obj interface{}) (string, error) { return obj.(*timestampedEntry).obj.(testStoreObject).id, nil }, }, clock.RealClock{}, ) err := ttlStore.Add(testObj) if err != nil { t.Errorf("Unable to add obj %#v", testObj) } item, exists, err := ttlStore.Get(testObj) if err != nil { t.Errorf("Failed to get from store, %v", err) } if exists || item != nil { t.Errorf("Got unexpected item %#v", item) } key, _ := testStoreKeyFunc(testObj) select { case delKey := <-deleteChan: if delKey != key { t.Errorf("Unexpected delete for key %s", key) } case <-time.After(wait.ForeverTestTimeout): t.Errorf("Unexpected timeout waiting on delete") } close(deleteChan) }
// getClientRepoConfig copies k8s.io/kubernetes/pkg/client/restclient.Config to // a k8s.io/client-go/pkg/client/restclient.Config. It's not a deep copy. Two // configs may share some common struct. func getClientRepoConfig(src *restclient.Config) (dst *clientreporestclient.Config) { skippedFields := sets.NewString("Transport", "WrapTransport", "RateLimiter", "AuthConfigPersister") dst = &clientreporestclient.Config{} dst.Transport = src.Transport dst.WrapTransport = src.WrapTransport dst.RateLimiter = src.RateLimiter dst.AuthConfigPersister = src.AuthConfigPersister sv := reflect.ValueOf(src).Elem() dv := reflect.ValueOf(dst).Elem() for i := 0; i < sv.NumField(); i++ { if skippedFields.Has(sv.Type().Field(i).Name) { continue } sf := sv.Field(i).Interface() data, err := json.Marshal(sf) if err != nil { Expect(err).NotTo(HaveOccurred()) } if !dv.Field(i).CanAddr() { Failf("unaddressable field: %v", dv.Type().Field(i).Name) } else { if err := json.Unmarshal(data, dv.Field(i).Addr().Interface()); err != nil { Expect(err).NotTo(HaveOccurred()) } } } return dst }
// parseIdentifiersList parses a (possibly empty) list of // of comma separated (possibly empty) identifiers func (p *Parser) parseIdentifiersList() (sets.String, error) { s := sets.NewString() for { tok, lit := p.consume(Values) switch tok { case IdentifierToken: s.Insert(lit) tok2, lit2 := p.lookahead(Values) switch tok2 { case CommaToken: continue case ClosedParToken: return s, nil default: return nil, fmt.Errorf("found '%s', expected: ',' or ')'", lit2) } case CommaToken: // handled here since we can have "(," if s.Len() == 0 { s.Insert("") // to handle (, } tok2, _ := p.lookahead(Values) if tok2 == ClosedParToken { s.Insert("") // to handle ,) Double "" removed by StringSet return s, nil } if tok2 == CommaToken { p.consume(Values) s.Insert("") // to handle ,, Double "" removed by StringSet } default: // it can be operator return s, fmt.Errorf("found '%s', expected: ',', or identifier", lit) } } }
func TestTTLList(t *testing.T) { testObjs := []testStoreObject{ {id: "foo", val: "bar"}, {id: "foo1", val: "bar1"}, {id: "foo2", val: "bar2"}, } expireKeys := sets.NewString(testObjs[0].id, testObjs[2].id) deleteChan := make(chan string, len(testObjs)) defer close(deleteChan) ttlStore := NewFakeExpirationStore( testStoreKeyFunc, deleteChan, &FakeExpirationPolicy{ NeverExpire: sets.NewString(testObjs[1].id), RetrieveKeyFunc: func(obj interface{}) (string, error) { return obj.(*timestampedEntry).obj.(testStoreObject).id, nil }, }, clock.RealClock{}, ) for _, obj := range testObjs { err := ttlStore.Add(obj) if err != nil { t.Errorf("Unable to add obj %#v", obj) } } listObjs := ttlStore.List() if len(listObjs) != 1 || !reflect.DeepEqual(listObjs[0], testObjs[1]) { t.Errorf("List returned unexpected results %#v", listObjs) } // Make sure all our deletes come through in an acceptable rate (1/100ms) for expireKeys.Len() != 0 { select { case delKey := <-deleteChan: if !expireKeys.Has(delKey) { t.Errorf("Unexpected delete for key %s", delKey) } expireKeys.Delete(delKey) case <-time.After(wait.ForeverTestTimeout): t.Errorf("Unexpected timeout waiting on delete") return } } }
// EventAggregate identifies similar events and groups into a common event if required func (e *EventAggregator) EventAggregate(newEvent *v1.Event) (*v1.Event, error) { aggregateKey, localKey := e.keyFunc(newEvent) now := unversioned.NewTime(e.clock.Now()) record := aggregateRecord{localKeys: sets.NewString(), lastTimestamp: now} e.Lock() defer e.Unlock() value, found := e.cache.Get(aggregateKey) if found { record = value.(aggregateRecord) } // if the last event was far enough in the past, it is not aggregated, and we must reset state maxInterval := time.Duration(e.maxIntervalInSeconds) * time.Second interval := now.Time.Sub(record.lastTimestamp.Time) if interval > maxInterval { record = aggregateRecord{localKeys: sets.NewString()} } record.localKeys.Insert(localKey) record.lastTimestamp = now e.cache.Add(aggregateKey, record) if record.localKeys.Len() < e.maxEvents { return newEvent, nil } // do not grow our local key set any larger than max record.localKeys.PopAny() // create a new aggregate event eventCopy := &v1.Event{ ObjectMeta: v1.ObjectMeta{ Name: fmt.Sprintf("%v.%x", newEvent.InvolvedObject.Name, now.UnixNano()), Namespace: newEvent.Namespace, }, Count: 1, FirstTimestamp: now, InvolvedObject: newEvent.InvolvedObject, LastTimestamp: now, Message: e.messageFunc(newEvent), Type: newEvent.Type, Reason: newEvent.Reason, Source: newEvent.Source, } return eventCopy, nil }
func (gmf *GroupMetaFactory) newRESTMapper(scheme *runtime.Scheme, externalVersions []unversioned.GroupVersion, groupMeta *apimachinery.GroupMeta) meta.RESTMapper { // the list of kinds that are scoped at the root of the api hierarchy // if a kind is not enumerated here, it is assumed to have a namespace scope rootScoped := sets.NewString() if gmf.GroupArgs.RootScopedKinds != nil { rootScoped = gmf.GroupArgs.RootScopedKinds } ignoredKinds := sets.NewString() if gmf.GroupArgs.IgnoredKinds != nil { ignoredKinds = gmf.GroupArgs.IgnoredKinds } return api.NewDefaultRESTMapperFromScheme( externalVersions, groupMeta.InterfacesFor, gmf.GroupArgs.ImportPrefix, ignoredKinds, rootScoped, scheme, ) }
// parseExactValue parses the only value for exact match style func (p *Parser) parseExactValue() (sets.String, error) { s := sets.NewString() tok, lit := p.lookahead(Values) if tok == EndOfStringToken || tok == CommaToken { s.Insert("") return s, nil } tok, lit = p.consume(Values) if tok == IdentifierToken { s.Insert(lit) return s, nil } return nil, fmt.Errorf("found '%s', expected: identifier", lit) }
// LabelSelectorAsSelector converts the LabelSelector api type into a struct that implements // labels.Selector // Note: This function should be kept in sync with the selector methods in pkg/labels/selector.go func LabelSelectorAsSelector(ps *LabelSelector) (labels.Selector, error) { if ps == nil { return labels.Nothing(), nil } if len(ps.MatchLabels)+len(ps.MatchExpressions) == 0 { return labels.Everything(), nil } selector := labels.NewSelector() for k, v := range ps.MatchLabels { r, err := labels.NewRequirement(k, selection.Equals, sets.NewString(v)) if err != nil { return nil, err } selector = selector.Add(*r) } for _, expr := range ps.MatchExpressions { var op selection.Operator switch expr.Operator { case LabelSelectorOpIn: op = selection.In case LabelSelectorOpNotIn: op = selection.NotIn case LabelSelectorOpExists: op = selection.Exists case LabelSelectorOpDoesNotExist: op = selection.DoesNotExist default: return nil, fmt.Errorf("%q is not a valid pod selector operator", expr.Operator) } r, err := labels.NewRequirement(expr.Key, op, sets.NewString(expr.Values...)) if err != nil { return nil, err } selector = selector.Add(*r) } return selector, nil }
func init() { if err := announced.NewGroupMetaFactory( &announced.GroupMetaFactoryArgs{ GroupName: certificates.GroupName, VersionPreferenceOrder: []string{v1alpha1.SchemeGroupVersion.Version}, ImportPrefix: "k8s.io/client-go/1.5/pkg/apis/certificates", RootScopedKinds: sets.NewString("CertificateSigningRequest"), AddInternalObjectsToScheme: certificates.AddToScheme, }, announced.VersionToSchemeFunc{ v1alpha1.SchemeGroupVersion.Version: v1alpha1.AddToScheme, }, ).Announce().RegisterAndEnable(); err != nil { panic(err) } }
func init() { if err := announced.NewGroupMetaFactory( &announced.GroupMetaFactoryArgs{ GroupName: storage.GroupName, VersionPreferenceOrder: []string{v1beta1.SchemeGroupVersion.Version}, ImportPrefix: "k8s.io/client-go/1.5/pkg/apis/storage", RootScopedKinds: sets.NewString("StorageClass"), AddInternalObjectsToScheme: storage.AddToScheme, }, announced.VersionToSchemeFunc{ v1beta1.SchemeGroupVersion.Version: v1beta1.AddToScheme, }, ).Announce().RegisterAndEnable(); err != nil { panic(err) } }
func init() { if err := announced.NewGroupMetaFactory( &announced.GroupMetaFactoryArgs{ GroupName: extensions.GroupName, VersionPreferenceOrder: []string{v1beta1.SchemeGroupVersion.Version}, ImportPrefix: "k8s.io/client-go/1.5/pkg/apis/extensions", RootScopedKinds: sets.NewString("PodSecurityPolicy", "ThirdPartyResource"), AddInternalObjectsToScheme: extensions.AddToScheme, }, announced.VersionToSchemeFunc{ v1beta1.SchemeGroupVersion.Version: v1beta1.AddToScheme, }, ).Announce().RegisterAndEnable(); err != nil { panic(err) } }
// Register constructs the finalized prioritized version list and sanity checks // the announced group & versions. Then it calls register. func (gmf *GroupMetaFactory) Register(m *registered.APIRegistrationManager) error { if gmf.GroupArgs == nil { return fmt.Errorf("partially announced groups are not allowed, only got versions: %#v", gmf.VersionArgs) } if len(gmf.VersionArgs) == 0 { return fmt.Errorf("group %v announced but no versions announced", gmf.GroupArgs.GroupName) } pvSet := sets.NewString(gmf.GroupArgs.VersionPreferenceOrder...) if pvSet.Len() != len(gmf.GroupArgs.VersionPreferenceOrder) { return fmt.Errorf("preference order for group %v has duplicates: %v", gmf.GroupArgs.GroupName, gmf.GroupArgs.VersionPreferenceOrder) } prioritizedVersions := []unversioned.GroupVersion{} for _, v := range gmf.GroupArgs.VersionPreferenceOrder { prioritizedVersions = append( prioritizedVersions, unversioned.GroupVersion{ Group: gmf.GroupArgs.GroupName, Version: v, }, ) } // Go through versions that weren't explicitly prioritized. unprioritizedVersions := []unversioned.GroupVersion{} for _, v := range gmf.VersionArgs { if v.GroupName != gmf.GroupArgs.GroupName { return fmt.Errorf("found %v/%v in group %v?", v.GroupName, v.VersionName, gmf.GroupArgs.GroupName) } if pvSet.Has(v.VersionName) { pvSet.Delete(v.VersionName) continue } unprioritizedVersions = append(unprioritizedVersions, unversioned.GroupVersion{Group: v.GroupName, Version: v.VersionName}) } if len(unprioritizedVersions) > 1 { glog.Warningf("group %v has multiple unprioritized versions: %#v. They will have an arbitrary preference order!", gmf.GroupArgs.GroupName, unprioritizedVersions) } if pvSet.Len() != 0 { return fmt.Errorf("group %v has versions in the priority list that were never announced: %s", gmf.GroupArgs.GroupName, pvSet) } prioritizedVersions = append(prioritizedVersions, unprioritizedVersions...) m.RegisterVersions(prioritizedVersions) gmf.prioritizedVersionList = prioritizedVersions return nil }
// SelectorFromSet returns a Selector which will match exactly the given Set. A // nil and empty Sets are considered equivalent to Everything(). func SelectorFromSet(ls Set) Selector { if ls == nil { return internalSelector{} } var requirements internalSelector for label, value := range ls { if r, err := NewRequirement(label, selection.Equals, sets.NewString(value)); err != nil { //TODO: double check errors when input comes from serialization? return internalSelector{} } else { requirements = append(requirements, *r) } } // sort to have deterministic string representation sort.Sort(ByKey(requirements)) return internalSelector(requirements) }
// Resync will touch all objects to put them into the processing queue func (f *FIFO) Resync() error { f.lock.Lock() defer f.lock.Unlock() inQueue := sets.NewString() for _, id := range f.queue { inQueue.Insert(id) } for id := range f.items { if !inQueue.Has(id) { f.queue = append(f.queue, id) } } if len(f.queue) > 0 { f.cond.Broadcast() } return nil }
// AliasesForResource finds the first alias response for the provided mappers. func (m MultiRESTMapper) AliasesForResource(alias string) ([]string, bool) { seenAliases := sets.NewString() allAliases := []string{} handled := false for _, t := range m { if currAliases, currOk := t.AliasesForResource(alias); currOk { for _, currAlias := range currAliases { if !seenAliases.Has(currAlias) { allAliases = append(allAliases, currAlias) seenAliases.Insert(currAlias) } } handled = true } } return allAliases, handled }
func TestStoreToNodeLister(t *testing.T) { store := NewStore(MetaNamespaceKeyFunc) ids := sets.NewString("foo", "bar", "baz") for id := range ids { store.Add(&api.Node{ObjectMeta: api.ObjectMeta{Name: id}}) } sml := StoreToNodeLister{store} gotNodes, err := sml.List() if err != nil { t.Fatalf("Unexpected error: %v", err) } got := make([]string, len(gotNodes.Items)) for ix := range gotNodes.Items { got[ix] = gotNodes.Items[ix].Name } if !ids.HasAll(got...) || len(got) != len(ids) { t.Errorf("Expected %v, got %v", ids, got) } }
// parseValues parses the values for set based matching (x,y,z) func (p *Parser) parseValues() (sets.String, error) { tok, lit := p.consume(Values) if tok != OpenParToken { return nil, fmt.Errorf("found '%s' expected: '('", lit) } tok, lit = p.lookahead(Values) switch tok { case IdentifierToken, CommaToken: s, err := p.parseIdentifiersList() // handles general cases if err != nil { return s, err } if tok, _ = p.consume(Values); tok != ClosedParToken { return nil, fmt.Errorf("found '%s', expected: ')'", lit) } return s, nil case ClosedParToken: // handles "()" p.consume(Values) return sets.NewString(""), nil default: return nil, fmt.Errorf("found '%s', expected: ',', ')' or identifier", lit) } }
func TestStoreToDaemonSetLister(t *testing.T) { store := NewStore(MetaNamespaceKeyFunc) lister := StoreToDaemonSetLister{store} testCases := []struct { inDSs []*extensions.DaemonSet list func() ([]extensions.DaemonSet, error) outDaemonSetNames sets.String expectErr bool }{ // Basic listing { inDSs: []*extensions.DaemonSet{ {ObjectMeta: api.ObjectMeta{Name: "basic"}}, }, list: func() ([]extensions.DaemonSet, error) { list, err := lister.List() return list.Items, err }, outDaemonSetNames: sets.NewString("basic"), }, // Listing multiple daemon sets { inDSs: []*extensions.DaemonSet{ {ObjectMeta: api.ObjectMeta{Name: "basic"}}, {ObjectMeta: api.ObjectMeta{Name: "complex"}}, {ObjectMeta: api.ObjectMeta{Name: "complex2"}}, }, list: func() ([]extensions.DaemonSet, error) { list, err := lister.List() return list.Items, err }, outDaemonSetNames: sets.NewString("basic", "complex", "complex2"), }, // No pod labels { inDSs: []*extensions.DaemonSet{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, Spec: extensions.DaemonSetSpec{ Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "baz"}}, }, }, }, list: func() ([]extensions.DaemonSet, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "pod1", Namespace: "ns"}, } return lister.GetPodDaemonSets(pod) }, outDaemonSetNames: sets.NewString(), expectErr: true, }, // No DS selectors { inDSs: []*extensions.DaemonSet{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, }, }, list: func() ([]extensions.DaemonSet, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod1", Namespace: "ns", Labels: map[string]string{"foo": "bar"}, }, } return lister.GetPodDaemonSets(pod) }, outDaemonSetNames: sets.NewString(), expectErr: true, }, // Matching labels to selectors and namespace { inDSs: []*extensions.DaemonSet{ { ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: extensions.DaemonSetSpec{ Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, }, }, { ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"}, Spec: extensions.DaemonSetSpec{ Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, }, }, }, list: func() ([]extensions.DaemonSet, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod1", Labels: map[string]string{"foo": "bar"}, Namespace: "ns", }, } return lister.GetPodDaemonSets(pod) }, outDaemonSetNames: sets.NewString("bar"), }, } for _, c := range testCases { for _, r := range c.inDSs { store.Add(r) } daemonSets, err := c.list() if err != nil && c.expectErr { continue } else if c.expectErr { t.Error("Expected error, got none") continue } else if err != nil { t.Errorf("Unexpected error %#v", err) continue } daemonSetNames := make([]string, len(daemonSets)) for ix := range daemonSets { daemonSetNames[ix] = daemonSets[ix].Name } if !c.outDaemonSetNames.HasAll(daemonSetNames...) || len(daemonSetNames) != len(c.outDaemonSetNames) { t.Errorf("Unexpected got controllers %+v expected %+v", daemonSetNames, c.outDaemonSetNames) } } }
// SelectorFromValidatedSet returns a Selector which will match exactly the given Set. // A nil and empty Sets are considered equivalent to Everything(). // It assumes that Set is already validated and doesn't do any validation. func SelectorFromValidatedSet(ls Set) Selector { if ls == nil { return internalSelector{} } var requirements internalSelector for label, value := range ls { requirements = append(requirements, Requirement{key: label, operator: selection.Equals, strValues: sets.NewString(value)}) } // sort to have deterministic string representation sort.Sort(ByKey(requirements)) return internalSelector(requirements) }
func TestStoreToReplicationControllerLister(t *testing.T) { testCases := []struct { description string inRCs []*api.ReplicationController list func(StoreToReplicationControllerLister) ([]api.ReplicationController, error) outRCNames sets.String expectErr bool onlyIfIndexedByNamespace bool }{ { description: "Verify we can search all namespaces", inRCs: []*api.ReplicationController{ { ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "bar"}, }, { ObjectMeta: api.ObjectMeta{Name: "hmm", Namespace: "hmm"}, }, }, list: func(lister StoreToReplicationControllerLister) ([]api.ReplicationController, error) { return lister.ReplicationControllers(api.NamespaceAll).List(labels.Set{}.AsSelectorPreValidated()) }, outRCNames: sets.NewString("hmm", "foo"), }, { description: "Verify we can search a specific namespace", inRCs: []*api.ReplicationController{ { ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "bar"}, }, { ObjectMeta: api.ObjectMeta{Name: "hmm", Namespace: "hmm"}, }, }, list: func(lister StoreToReplicationControllerLister) ([]api.ReplicationController, error) { return lister.ReplicationControllers("hmm").List(labels.Set{}.AsSelectorPreValidated()) }, outRCNames: sets.NewString("hmm"), }, { description: "Basic listing with all labels and no selectors", inRCs: []*api.ReplicationController{ {ObjectMeta: api.ObjectMeta{Name: "basic"}}, }, list: func(lister StoreToReplicationControllerLister) ([]api.ReplicationController, error) { return lister.List() }, outRCNames: sets.NewString("basic"), }, { description: "No pod labels", inRCs: []*api.ReplicationController{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, Spec: api.ReplicationControllerSpec{ Selector: map[string]string{"foo": "baz"}, }, }, }, list: func(lister StoreToReplicationControllerLister) ([]api.ReplicationController, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "pod1", Namespace: "ns"}, } return lister.GetPodControllers(pod) }, outRCNames: sets.NewString(), expectErr: true, }, { description: "No RC selectors", inRCs: []*api.ReplicationController{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, }, }, list: func(lister StoreToReplicationControllerLister) ([]api.ReplicationController, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod1", Namespace: "ns", Labels: map[string]string{"foo": "bar"}, }, } return lister.GetPodControllers(pod) }, outRCNames: sets.NewString(), expectErr: true, }, { description: "Matching labels to selectors and namespace", inRCs: []*api.ReplicationController{ { ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: api.ReplicationControllerSpec{ Selector: map[string]string{"foo": "bar"}, }, }, { ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"}, Spec: api.ReplicationControllerSpec{ Selector: map[string]string{"foo": "bar"}, }, }, }, list: func(lister StoreToReplicationControllerLister) ([]api.ReplicationController, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod1", Labels: map[string]string{"foo": "bar"}, Namespace: "ns", }, } return lister.GetPodControllers(pod) }, outRCNames: sets.NewString("bar"), onlyIfIndexedByNamespace: true, }, } for _, c := range testCases { for _, withIndex := range []bool{true, false} { if c.onlyIfIndexedByNamespace && !withIndex { continue } var store Indexer if withIndex { store = NewIndexer(MetaNamespaceKeyFunc, Indexers{NamespaceIndex: MetaNamespaceIndexFunc}) } else { store = NewIndexer(MetaNamespaceKeyFunc, Indexers{}) } for _, r := range c.inRCs { store.Add(r) } gotControllers, err := c.list(StoreToReplicationControllerLister{store}) if err != nil && c.expectErr { continue } else if c.expectErr { t.Errorf("(%q, withIndex=%v) Expected error, got none", c.description, withIndex) continue } else if err != nil { t.Errorf("(%q, withIndex=%v) Unexpected error %#v", c.description, withIndex, err) continue } gotNames := make([]string, len(gotControllers)) for ix := range gotControllers { gotNames[ix] = gotControllers[ix].Name } if !c.outRCNames.HasAll(gotNames...) || len(gotNames) != len(c.outRCNames) { t.Errorf("(%q, withIndex=%v) Unexpected got controllers %+v expected %+v", c.description, withIndex, gotNames, c.outRCNames) } } } }
func TestStoreToReplicaSetLister(t *testing.T) { store := NewStore(MetaNamespaceKeyFunc) lister := StoreToReplicaSetLister{store} testCases := []struct { inRSs []*extensions.ReplicaSet list func() ([]extensions.ReplicaSet, error) outRSNames sets.String expectErr bool }{ // Basic listing with all labels and no selectors { inRSs: []*extensions.ReplicaSet{ {ObjectMeta: api.ObjectMeta{Name: "basic"}}, }, list: func() ([]extensions.ReplicaSet, error) { return lister.List() }, outRSNames: sets.NewString("basic"), }, // No pod labels { inRSs: []*extensions.ReplicaSet{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, Spec: extensions.ReplicaSetSpec{ Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "baz"}}, }, }, }, list: func() ([]extensions.ReplicaSet, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "pod1", Namespace: "ns"}, } return lister.GetPodReplicaSets(pod) }, outRSNames: sets.NewString(), expectErr: true, }, // No ReplicaSet selectors { inRSs: []*extensions.ReplicaSet{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, }, }, list: func() ([]extensions.ReplicaSet, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod1", Namespace: "ns", Labels: map[string]string{"foo": "bar"}, }, } return lister.GetPodReplicaSets(pod) }, outRSNames: sets.NewString(), expectErr: true, }, // Matching labels to selectors and namespace { inRSs: []*extensions.ReplicaSet{ { ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: extensions.ReplicaSetSpec{ Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, }, }, { ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"}, Spec: extensions.ReplicaSetSpec{ Selector: &unversioned.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}}, }, }, }, list: func() ([]extensions.ReplicaSet, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod1", Labels: map[string]string{"foo": "bar"}, Namespace: "ns", }, } return lister.GetPodReplicaSets(pod) }, outRSNames: sets.NewString("bar"), }, } for _, c := range testCases { for _, r := range c.inRSs { store.Add(r) } gotRSs, err := c.list() if err != nil && c.expectErr { continue } else if c.expectErr { t.Error("Expected error, got none") continue } else if err != nil { t.Errorf("Unexpected error %#v", err) continue } gotNames := make([]string, len(gotRSs)) for ix := range gotRSs { gotNames[ix] = gotRSs[ix].Name } if !c.outRSNames.HasAll(gotNames...) || len(gotNames) != len(c.outRSNames) { t.Errorf("Unexpected got ReplicaSets %+v expected %+v", gotNames, c.outRSNames) } } }
func TestStoreToNodeConditionLister(t *testing.T) { store := NewStore(MetaNamespaceKeyFunc) nodes := []*api.Node{ { ObjectMeta: api.ObjectMeta{Name: "foo"}, Status: api.NodeStatus{ Conditions: []api.NodeCondition{ { Type: api.NodeReady, Status: api.ConditionTrue, }, { Type: api.NodeOutOfDisk, Status: api.ConditionFalse, }, }, }, }, { ObjectMeta: api.ObjectMeta{Name: "bar"}, Status: api.NodeStatus{ Conditions: []api.NodeCondition{ { Type: api.NodeOutOfDisk, Status: api.ConditionTrue, }, }, }, }, { ObjectMeta: api.ObjectMeta{Name: "baz"}, Status: api.NodeStatus{ Conditions: []api.NodeCondition{ { Type: api.NodeReady, Status: api.ConditionFalse, }, { Type: api.NodeOutOfDisk, Status: api.ConditionUnknown, }, }, }, }, } for _, n := range nodes { store.Add(n) } predicate := func(node *api.Node) bool { for _, cond := range node.Status.Conditions { if cond.Type == api.NodeOutOfDisk && cond.Status == api.ConditionTrue { return false } } return true } snl := StoreToNodeLister{store} sncl := snl.NodeCondition(predicate) want := sets.NewString("foo", "baz") gotNodes, err := sncl.List() if err != nil { t.Fatalf("Unexpected error: %v", err) } got := make([]string, len(gotNodes)) for ix := range gotNodes { got[ix] = gotNodes[ix].Name } if !want.HasAll(got...) || len(got) != len(want) { t.Errorf("Expected %v, got %v", want, got) } }
return a.Cmp(b) == 0 }, func(a, b unversioned.Time) bool { return a.UTC() == b.UTC() }, func(a, b labels.Selector) bool { return a.String() == b.String() }, func(a, b fields.Selector) bool { return a.String() == b.String() }, ) var standardResourceQuotaScopes = sets.NewString( string(ResourceQuotaScopeTerminating), string(ResourceQuotaScopeNotTerminating), string(ResourceQuotaScopeBestEffort), string(ResourceQuotaScopeNotBestEffort), ) // IsStandardResourceQuotaScope returns true if the scope is a standard value func IsStandardResourceQuotaScope(str string) bool { return standardResourceQuotaScopes.Has(str) } var podObjectCountQuotaResources = sets.NewString( string(ResourcePods), ) var podComputeQuotaResources = sets.NewString( string(ResourceCPU), string(ResourceMemory),
func TestStoreToJobLister(t *testing.T) { store := NewStore(MetaNamespaceKeyFunc) lister := StoreToJobLister{store} testCases := []struct { inJobs []*batch.Job list func() ([]batch.Job, error) outJobNames sets.String expectErr bool msg string }{ // Basic listing { inJobs: []*batch.Job{ {ObjectMeta: api.ObjectMeta{Name: "basic"}}, }, list: func() ([]batch.Job, error) { list, err := lister.List() return list.Items, err }, outJobNames: sets.NewString("basic"), msg: "basic listing failed", }, // Listing multiple jobs { inJobs: []*batch.Job{ {ObjectMeta: api.ObjectMeta{Name: "basic"}}, {ObjectMeta: api.ObjectMeta{Name: "complex"}}, {ObjectMeta: api.ObjectMeta{Name: "complex2"}}, }, list: func() ([]batch.Job, error) { list, err := lister.List() return list.Items, err }, outJobNames: sets.NewString("basic", "complex", "complex2"), msg: "listing multiple jobs failed", }, // No pod labels { inJobs: []*batch.Job{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, Spec: batch.JobSpec{ Selector: &unversioned.LabelSelector{ MatchLabels: map[string]string{"foo": "baz"}, }, }, }, }, list: func() ([]batch.Job, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "pod", Namespace: "ns"}, } return lister.GetPodJobs(pod) }, outJobNames: sets.NewString(), expectErr: true, msg: "listing jobs failed when pod has no labels: expected error, got none", }, // No Job selectors { inJobs: []*batch.Job{ { ObjectMeta: api.ObjectMeta{Name: "basic", Namespace: "ns"}, }, }, list: func() ([]batch.Job, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod", Namespace: "ns", Labels: map[string]string{"foo": "bar"}, }, } return lister.GetPodJobs(pod) }, outJobNames: sets.NewString(), expectErr: true, msg: "listing jobs failed when job has no selector: expected error, got none", }, // Matching labels to selectors and namespace { inJobs: []*batch.Job{ { ObjectMeta: api.ObjectMeta{Name: "foo"}, Spec: batch.JobSpec{ Selector: &unversioned.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, }, }, { ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "ns"}, Spec: batch.JobSpec{ Selector: &unversioned.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, }, }, }, list: func() ([]batch.Job, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod", Labels: map[string]string{"foo": "bar"}, Namespace: "ns", }, } return lister.GetPodJobs(pod) }, outJobNames: sets.NewString("bar"), msg: "listing jobs with namespace and selector failed", }, // Matching labels to selectors and namespace, error case { inJobs: []*batch.Job{ { ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "foo"}, Spec: batch.JobSpec{ Selector: &unversioned.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, }, }, { ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "bar"}, Spec: batch.JobSpec{ Selector: &unversioned.LabelSelector{ MatchLabels: map[string]string{"foo": "bar"}, }, }, }, }, list: func() ([]batch.Job, error) { pod := &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod", Labels: map[string]string{"foo": "bar"}, Namespace: "baz", }, } return lister.GetPodJobs(pod) }, expectErr: true, msg: "listing jobs with namespace and selector failed: expected error, got none", }, } for _, c := range testCases { for _, r := range c.inJobs { store.Add(r) } Jobs, err := c.list() if err != nil && c.expectErr { continue } else if c.expectErr { t.Errorf("%v", c.msg) continue } else if err != nil { t.Errorf("Unexpected error %#v", err) continue } JobNames := make([]string, len(Jobs)) for ix := range Jobs { JobNames[ix] = Jobs[ix].Name } if !c.outJobNames.HasAll(JobNames...) || len(JobNames) != len(c.outJobNames) { t.Errorf("%v : expected %v, got %v", c.msg, JobNames, c.outJobNames) } } }