diff --git a/cmd/cloudcfg/cloudcfg.go b/cmd/cloudcfg/cloudcfg.go index 99380f84da..2ba1cc3216 100644 --- a/cmd/cloudcfg/cloudcfg.go +++ b/cmd/cloudcfg/cloudcfg.go @@ -39,7 +39,7 @@ var ( versionFlag = flag.Bool("v", false, "Print the version number.") httpServer = flag.String("h", "", "The host to connect to.") config = flag.String("c", "", "Path to the config file.") - labelQuery = flag.String("l", "", "Label query to use for listing") + selector = flag.String("l", "", "Selector (label query) to use for listing") updatePeriod = flag.Duration("u", 60*time.Second, "Update interarrival period") portSpec = flag.String("p", "", "The port spec, comma-separated list of :,...") servicePort = flag.Int("s", -1, "If positive, create and run a corresponding service on this port, only used with 'run'") @@ -143,8 +143,8 @@ func executeAPIRequest(method string, auth *kube_client.AuthInfo) bool { switch method { case "get", "list": url := readUrl(parseStorage()) - if len(*labelQuery) > 0 && method == "list" { - url = url + "?labels=" + *labelQuery + if len(*selector) > 0 && method == "list" { + url = url + "?labels=" + *selector } request, err = http.NewRequest("GET", url, nil) case "delete": diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index ea58302a0b..c7d638e851 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -31,7 +31,7 @@ import ( // RESTStorage is a generic interface for RESTful storage services type RESTStorage interface { - List(labels.Query) (interface{}, error) + List(labels.Selector) (interface{}, error) Get(id string) (interface{}, error) Delete(id string) error Extract(body string) (interface{}, error) @@ -149,12 +149,12 @@ func (server *ApiServer) handleREST(parts []string, requestUrl *url.URL, req *ht case "GET": switch len(parts) { case 1: - query, err := labels.ParseQuery(requestUrl.Query().Get("labels")) + selector, err := labels.ParseSelector(requestUrl.Query().Get("labels")) if err != nil { server.error(err, w) return } - controllers, err := storage.List(query) + controllers, err := storage.List(selector) if err != nil { server.error(err, w) return diff --git a/pkg/apiserver/apiserver_test.go b/pkg/apiserver/apiserver_test.go index 41197d5b7e..c10ca1939e 100644 --- a/pkg/apiserver/apiserver_test.go +++ b/pkg/apiserver/apiserver_test.go @@ -51,7 +51,7 @@ type SimpleRESTStorage struct { updated Simple } -func (storage *SimpleRESTStorage) List(labels.Query) (interface{}, error) { +func (storage *SimpleRESTStorage) List(labels.Selector) (interface{}, error) { result := SimpleList{ Items: storage.list, } diff --git a/pkg/client/client.go b/pkg/client/client.go index 90300589d1..3d137b5be3 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -33,7 +33,7 @@ import ( // ClientInterface holds the methods for clients of Kubenetes, an interface to allow mock testing type ClientInterface interface { - ListPods(labelQuery map[string]string) (api.PodList, error) + ListPods(selector map[string]string) (api.PodList, error) GetPod(name string) (api.Pod, error) DeletePod(name string) error CreatePod(api.Pod) (api.Pod, error) @@ -112,40 +112,40 @@ func (client Client) makeURL(path string) string { return client.Host + "/api/v1beta1/" + path } -// EncodeLabelQuery transforms a label query expressed as a key/value map, into a +// EncodeSelector transforms a selector expressed as a key/value map, into a // comma separated, key=value encoding. -func EncodeLabelQuery(labelQuery map[string]string) string { - query := make([]string, 0, len(labelQuery)) - for key, value := range labelQuery { - query = append(query, key+"="+value) +func EncodeSelector(selector map[string]string) string { + parts := make([]string, 0, len(selector)) + for key, value := range selector { + parts = append(parts, key+"="+value) } - return url.QueryEscape(strings.Join(query, ",")) + return url.QueryEscape(strings.Join(parts, ",")) } -// DecodeLabelQuery transforms a label query from a comma separated, key=value format into +// DecodeSelector transforms a selector from a comma separated, key=value format into // a key/value map. -func DecodeLabelQuery(labelQuery string) map[string]string { +func DecodeSelector(selector string) map[string]string { result := map[string]string{} - if len(labelQuery) == 0 { + if len(selector) == 0 { return result } - parts := strings.Split(labelQuery, ",") + parts := strings.Split(selector, ",") for _, part := range parts { pieces := strings.Split(part, "=") if len(pieces) == 2 { result[pieces[0]] = pieces[1] } else { - log.Printf("Invalid label query: %s", labelQuery) + log.Printf("Invalid selector: %s", selector) } } return result } -// ListPods takes a label query, and returns the list of pods that match that query -func (client Client) ListPods(labelQuery map[string]string) (api.PodList, error) { +// ListPods takes a selector, and returns the list of pods that match that selector +func (client Client) ListPods(selector map[string]string) (api.PodList, error) { path := "pods" - if labelQuery != nil && len(labelQuery) > 0 { - path += "?labels=" + EncodeLabelQuery(labelQuery) + if selector != nil && len(selector) > 0 { + path += "?labels=" + EncodeSelector(selector) } var result api.PodList _, err := client.rawRequest("GET", path, nil, &result) diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go index 9cd7cf404f..4b08f34e23 100644 --- a/pkg/client/client_test.go +++ b/pkg/client/client_test.go @@ -117,13 +117,13 @@ func TestListPodsLabels(t *testing.T) { client := Client{ Host: testServer.URL, } - query := map[string]string{"foo": "bar", "name": "baz"} - receivedPodList, err := client.ListPods(query) + selector := map[string]string{"foo": "bar", "name": "baz"} + receivedPodList, err := client.ListPods(selector) fakeHandler.ValidateRequest(t, makeUrl("/pods"), "GET", nil) - queryString := fakeHandler.RequestReceived.URL.Query().Get("labels") - queryString, _ = url.QueryUnescape(queryString) - parsedQueryString := DecodeLabelQuery(queryString) - expectEqual(t, query, parsedQueryString) + selectorString := fakeHandler.RequestReceived.URL.Query().Get("labels") + selectorString, _ = url.QueryUnescape(selectorString) + parsedSelectorString := DecodeSelector(selectorString) + expectEqual(t, selector, parsedSelectorString) if err != nil { t.Errorf("Unexpected error in listing pods: %#v", err) } diff --git a/pkg/cloudcfg/cloudcfg_test.go b/pkg/cloudcfg/cloudcfg_test.go index de23e61216..a1b3ffc089 100644 --- a/pkg/cloudcfg/cloudcfg_test.go +++ b/pkg/cloudcfg/cloudcfg_test.go @@ -46,7 +46,7 @@ type FakeKubeClient struct { ctrl api.ReplicationController } -func (client *FakeKubeClient) ListPods(labelQuery map[string]string) (api.PodList, error) { +func (client *FakeKubeClient) ListPods(selector map[string]string) (api.PodList, error) { client.actions = append(client.actions, Action{action: "list-pods"}) return client.pods, nil } diff --git a/pkg/cloudcfg/resource_printer.go b/pkg/cloudcfg/resource_printer.go index d72bfd384e..648e42c7f1 100644 --- a/pkg/cloudcfg/resource_printer.go +++ b/pkg/cloudcfg/resource_printer.go @@ -62,7 +62,7 @@ func (y *YAMLPrinter) Print(data string, w io.Writer) error { type HumanReadablePrinter struct{} var podColumns = []string{"Name", "Image(s)", "Host", "Labels"} -var replicationControllerColumns = []string{"Name", "Image(s)", "Label Query", "Replicas"} +var replicationControllerColumns = []string{"Name", "Image(s)", "Selector", "Replicas"} var serviceColumns = []string{"Name", "Labels", "Selector", "Port"} func (h *HumanReadablePrinter) unknown(data string, w io.Writer) error { diff --git a/pkg/kubelet/kubelet_server.go b/pkg/kubelet/kubelet_server.go index 9eaf5b8e44..943e0ac20a 100644 --- a/pkg/kubelet/kubelet_server.go +++ b/pkg/kubelet/kubelet_server.go @@ -68,7 +68,7 @@ func (s *KubeletServer) ServeHTTP(w http.ResponseWriter, req *http.Request) { container := u.Query().Get("container") if len(container) == 0 { w.WriteHeader(http.StatusBadRequest) - fmt.Fprint(w, "Missing container query arg.") + fmt.Fprint(w, "Missing container selector arg.") return } id, found, err := s.Kubelet.GetContainerID(container) diff --git a/pkg/labels/doc.go b/pkg/labels/doc.go index 54318e41bb..afc8c27c64 100644 --- a/pkg/labels/doc.go +++ b/pkg/labels/doc.go @@ -14,6 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package labels implements a simple label system, parsing and matching queries -// with sets of labels. +// Package labels implements a simple label system, parsing and matching +// selectors with sets of labels. package labels diff --git a/pkg/labels/labels.go b/pkg/labels/labels.go index 35a800126c..351289ea63 100644 --- a/pkg/labels/labels.go +++ b/pkg/labels/labels.go @@ -30,15 +30,15 @@ type Labels interface { type Set map[string]string // All labels listed as a human readable string. Conveniently, exactly the format -// that ParseQuery takes. +// that ParseSelector takes. func (ls Set) String() string { - query := make([]string, 0, len(ls)) + selector := make([]string, 0, len(ls)) for key, value := range ls { - query = append(query, key+"="+value) + selector = append(selector, key+"="+value) } // Sort for determinism. - sort.StringSlice(query).Sort() - return strings.Join(query, ",") + sort.StringSlice(selector).Sort() + return strings.Join(selector, ",") } // Implement Labels interface. @@ -46,7 +46,7 @@ func (ls Set) Get(label string) string { return ls[label] } -// Convenience function: convert these labels to a query. -func (ls Set) AsQuery() Query { - return QueryFromSet(ls) +// Convenience function: convert these labels to a selector. +func (ls Set) AsSelector() Selector { + return SelectorFromSet(ls) } diff --git a/pkg/labels/query.go b/pkg/labels/query.go index 5e563924a3..52e712cb3c 100644 --- a/pkg/labels/query.go +++ b/pkg/labels/query.go @@ -21,17 +21,17 @@ import ( "strings" ) -// Represents a label query. -type Query interface { - // Returns true if this query matches the given set of labels. +// Represents a selector. +type Selector interface { + // Returns true if this selector matches the given set of labels. Matches(Labels) bool - // Prints a human readable version of this label query. + // Prints a human readable version of this selector. String() string } -// Everything returns a query that matches all labels. -func Everything() Query { +// Everything returns a selector that matches all labels. +func Everything() Selector { return andTerm{} } @@ -59,7 +59,7 @@ func (t *notHasTerm) String() string { return fmt.Sprintf("%v!=%v", t.label, t.value) } -type andTerm []Query +type andTerm []Selector func (t andTerm) Matches(ls Labels) bool { for _, q := range t { @@ -78,17 +78,17 @@ func (t andTerm) String() string { return strings.Join(terms, ",") } -func try(queryPiece, op string) (lhs, rhs string, ok bool) { - pieces := strings.Split(queryPiece, op) +func try(selectorPiece, op string) (lhs, rhs string, ok bool) { + pieces := strings.Split(selectorPiece, op) if len(pieces) == 2 { return pieces[0], pieces[1], true } return "", "", false } -// Given a Set, return a Query which will match exactly that Set. -func QueryFromSet(ls Set) Query { - var items []Query +// Given a Set, return a Selector which will match exactly that Set. +func SelectorFromSet(ls Set) Selector { + var items []Selector for label, value := range ls { items = append(items, &hasTerm{label: label, value: value}) } @@ -98,10 +98,10 @@ func QueryFromSet(ls Set) Query { return andTerm(items) } -// Takes a string repsenting a label query and returns an object suitable for matching, or an error. -func ParseQuery(query string) (Query, error) { - parts := strings.Split(query, ",") - var items []Query +// Takes a string repsenting a selector and returns an object suitable for matching, or an error. +func ParseSelector(selector string) (Selector, error) { + parts := strings.Split(selector, ",") + var items []Selector for _, part := range parts { if part == "" { continue @@ -113,7 +113,7 @@ func ParseQuery(query string) (Query, error) { } else if lhs, rhs, ok := try(part, "="); ok { items = append(items, &hasTerm{label: lhs, value: rhs}) } else { - return nil, fmt.Errorf("invalid label query: '%s'; can't understand '%s'", query, part) + return nil, fmt.Errorf("invalid selector: '%s'; can't understand '%s'", selector, part) } } if len(items) == 1 { diff --git a/pkg/labels/query_test.go b/pkg/labels/query_test.go index 38dae8b489..2947e042bf 100644 --- a/pkg/labels/query_test.go +++ b/pkg/labels/query_test.go @@ -20,7 +20,7 @@ import ( "testing" ) -func TestQueryParse(t *testing.T) { +func TestSelectorParse(t *testing.T) { testGoodStrings := []string{ "x=a,y=b,z=c", "", @@ -31,7 +31,7 @@ func TestQueryParse(t *testing.T) { "x==a==b", } for _, test := range testGoodStrings { - lq, err := ParseQuery(test) + lq, err := ParseSelector(test) if err != nil { t.Errorf("%v: error %v (%#v)\n", test, err, err) } @@ -40,42 +40,42 @@ func TestQueryParse(t *testing.T) { } } for _, test := range testBadStrings { - _, err := ParseQuery(test) + _, err := ParseSelector(test) if err == nil { t.Errorf("%v: did not get expected error\n", test) } } } -func expectMatch(t *testing.T, query string, ls Set) { - lq, err := ParseQuery(query) +func expectMatch(t *testing.T, selector string, ls Set) { + lq, err := ParseSelector(selector) if err != nil { - t.Errorf("Unable to parse %v as a query\n", query) + t.Errorf("Unable to parse %v as a selector\n", selector) return } if !lq.Matches(ls) { - t.Errorf("Wanted %s to match '%s', but it did not.\n", query, ls) + t.Errorf("Wanted %s to match '%s', but it did not.\n", selector, ls) } } -func expectNoMatch(t *testing.T, query string, ls Set) { - lq, err := ParseQuery(query) +func expectNoMatch(t *testing.T, selector string, ls Set) { + lq, err := ParseSelector(selector) if err != nil { - t.Errorf("Unable to parse %v as a query\n", query) + t.Errorf("Unable to parse %v as a selector\n", selector) return } if lq.Matches(ls) { - t.Errorf("Wanted '%s' to not match '%s', but it did.", query, ls) + t.Errorf("Wanted '%s' to not match '%s', but it did.", selector, ls) } } func TestEverything(t *testing.T) { if !Everything().Matches(Set{"x": "y"}) { - t.Errorf("Nil query didn't match") + t.Errorf("Nil selector didn't match") } } -func TestLabelQueryMatches(t *testing.T) { +func TestSelectorMatches(t *testing.T) { expectMatch(t, "", Set{"x": "y"}) expectMatch(t, "x=y", Set{"x": "y"}) expectMatch(t, "x=y,z=w", Set{"x": "y", "z": "w"}) @@ -96,15 +96,15 @@ func TestLabelQueryMatches(t *testing.T) { expectNoMatch(t, "foo=bar,foobar=bar,baz=blah", labelset) } -func expectMatchDirect(t *testing.T, query, ls Set) { - if !QueryFromSet(query).Matches(ls) { - t.Errorf("Wanted %s to match '%s', but it did not.\n", query, ls) +func expectMatchDirect(t *testing.T, selector, ls Set) { + if !SelectorFromSet(selector).Matches(ls) { + t.Errorf("Wanted %s to match '%s', but it did not.\n", selector, ls) } } -func expectNoMatchDirect(t *testing.T, query, ls Set) { - if QueryFromSet(query).Matches(ls) { - t.Errorf("Wanted '%s' to not match '%s', but it did.", query, ls) +func expectNoMatchDirect(t *testing.T, selector, ls Set) { + if SelectorFromSet(selector).Matches(ls) { + t.Errorf("Wanted '%s' to not match '%s', but it did.", selector, ls) } } diff --git a/pkg/registry/controller_registry.go b/pkg/registry/controller_registry.go index 1824ba965a..1b6aabab84 100644 --- a/pkg/registry/controller_registry.go +++ b/pkg/registry/controller_registry.go @@ -35,12 +35,12 @@ func MakeControllerRegistryStorage(registry ControllerRegistry) apiserver.RESTSt } } -func (storage *ControllerRegistryStorage) List(query labels.Query) (interface{}, error) { +func (storage *ControllerRegistryStorage) List(selector labels.Selector) (interface{}, error) { result := api.ReplicationControllerList{JSONBase: api.JSONBase{Kind: "cluster#replicationControllerList"}} controllers, err := storage.registry.ListControllers() if err == nil { for _, controller := range controllers { - if query.Matches(labels.Set(controller.Labels)) { + if selector.Matches(labels.Set(controller.Labels)) { result.Items = append(result.Items, controller) } } diff --git a/pkg/registry/endpoints.go b/pkg/registry/endpoints.go index 37257c9117..f29417a1e6 100644 --- a/pkg/registry/endpoints.go +++ b/pkg/registry/endpoints.go @@ -43,7 +43,7 @@ func (e *EndpointController) SyncServiceEndpoints() error { } var resultErr error for _, service := range services.Items { - pods, err := e.podRegistry.ListPods(labels.Set(service.Selector).AsQuery()) + pods, err := e.podRegistry.ListPods(labels.Set(service.Selector).AsSelector()) if err != nil { log.Printf("Error syncing service: %#v, skipping.", service) resultErr = err diff --git a/pkg/registry/etcd_registry.go b/pkg/registry/etcd_registry.go index 389e4b98ec..a4df170c15 100644 --- a/pkg/registry/etcd_registry.go +++ b/pkg/registry/etcd_registry.go @@ -59,7 +59,7 @@ func (registry *EtcdRegistry) helper() *util.EtcdHelper { return &util.EtcdHelper{registry.etcdClient} } -func (registry *EtcdRegistry) ListPods(query labels.Query) ([]api.Pod, error) { +func (registry *EtcdRegistry) ListPods(selector labels.Selector) ([]api.Pod, error) { pods := []api.Pod{} for _, machine := range registry.machines { var machinePods []api.Pod @@ -68,7 +68,7 @@ func (registry *EtcdRegistry) ListPods(query labels.Query) ([]api.Pod, error) { return pods, err } for _, pod := range machinePods { - if query.Matches(labels.Set(pod.Labels)) { + if selector.Matches(labels.Set(pod.Labels)) { pod.CurrentState.Host = machine pods = append(pods, pod) } diff --git a/pkg/registry/interfaces.go b/pkg/registry/interfaces.go index bf0e2728e9..de077447ff 100644 --- a/pkg/registry/interfaces.go +++ b/pkg/registry/interfaces.go @@ -22,8 +22,8 @@ import ( // PodRegistry is an interface implemented by things that know how to store Pod objects. type PodRegistry interface { - // ListPods obtains a list of pods that match query. - ListPods(query labels.Query) ([]api.Pod, error) + // ListPods obtains a list of pods that match selector. + ListPods(selector labels.Selector) ([]api.Pod, error) // Get a specific pod GetPod(podID string) (*api.Pod, error) // Create a pod based on a specification, schedule it onto a specific machine. diff --git a/pkg/registry/memory_registry.go b/pkg/registry/memory_registry.go index a217552591..994649df93 100644 --- a/pkg/registry/memory_registry.go +++ b/pkg/registry/memory_registry.go @@ -36,10 +36,10 @@ func MakeMemoryRegistry() *MemoryRegistry { } } -func (registry *MemoryRegistry) ListPods(query labels.Query) ([]api.Pod, error) { +func (registry *MemoryRegistry) ListPods(selector labels.Selector) ([]api.Pod, error) { result := []api.Pod{} for _, value := range registry.podData { - if query.Matches(labels.Set(value.Labels)) { + if selector.Matches(labels.Set(value.Labels)) { result = append(result, value) } } diff --git a/pkg/registry/pod_registry.go b/pkg/registry/pod_registry.go index 272238c689..75df1825a1 100644 --- a/pkg/registry/pod_registry.go +++ b/pkg/registry/pod_registry.go @@ -45,9 +45,9 @@ func MakePodRegistryStorage(registry PodRegistry, containerInfo client.Container } } -func (storage *PodRegistryStorage) List(query labels.Query) (interface{}, error) { +func (storage *PodRegistryStorage) List(selector labels.Selector) (interface{}, error) { var result api.PodList - pods, err := storage.registry.ListPods(query) + pods, err := storage.registry.ListPods(selector) if err == nil { result.Items = pods } diff --git a/pkg/registry/service_registry.go b/pkg/registry/service_registry.go index 128e3b571b..c30029bd71 100644 --- a/pkg/registry/service_registry.go +++ b/pkg/registry/service_registry.go @@ -59,7 +59,7 @@ func GetServiceEnvironmentVariables(registry ServiceRegistry, machine string) ([ return result, nil } -func (sr *ServiceRegistryStorage) List(query labels.Query) (interface{}, error) { +func (sr *ServiceRegistryStorage) List(selector labels.Selector) (interface{}, error) { list, err := sr.registry.ListServices() if err != nil { return nil, err @@ -67,7 +67,7 @@ func (sr *ServiceRegistryStorage) List(query labels.Query) (interface{}, error) list.Kind = "cluster#serviceList" var filtered []api.Service for _, service := range list.Items { - if query.Matches(labels.Set(service.Labels)) { + if selector.Matches(labels.Set(service.Labels)) { filtered = append(filtered, service) } }