Separate labels and selector in services for clarity

pull/6/head
Daniel Smith 2014-06-18 16:01:49 -07:00
parent 59c08db4c1
commit c4649d539b
8 changed files with 39 additions and 23 deletions

View File

@ -138,11 +138,17 @@ type ServiceList struct {
}
// Defines a service abstraction by a name (for example, mysql) consisting of local port
// (for example 3306) that the proxy listens on, and the labels that define the service.
// (for example 3306) that the proxy listens on, and the selector that determines which pods
// will answer requests sent through the proxy.
type Service struct {
JSONBase `json:",inline" yaml:",inline"`
Port int `json:"port,omitempty" yaml:"port,omitempty"`
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
JSONBase `json:",inline" yaml:",inline"`
Port int `json:"port,omitempty" yaml:"port,omitempty"`
// This service's labels.
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
// This service will route traffic to pods having labels matching this selector.
Selector map[string]string `json:"selector,omitempty" yaml:"selector,omitempty"`
CreateExternalLoadBalancer bool `json:"createExternalLoadBalancer,omitempty" yaml:"createExternalLoadBalancer,omitempty"`
}

View File

@ -255,6 +255,9 @@ func createService(name string, port int, client client.ClientInterface) (api.Se
Labels: map[string]string{
"name": name,
},
Selector: map[string]string{
"name": name,
},
}
svc, err := client.CreateService(svc)
return svc, err

View File

@ -63,6 +63,9 @@ func TestParseService(t *testing.T) {
Labels: map[string]string{
"area": "staging",
},
Selector: map[string]string{
"area": "staging",
},
})
}

View File

@ -24,6 +24,7 @@ import (
"text/tabwriter"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"gopkg.in/v1/yaml"
)
@ -62,7 +63,7 @@ type HumanReadablePrinter struct{}
var podColumns = []string{"Name", "Image(s)", "Host", "Labels"}
var replicationControllerColumns = []string{"Name", "Image(s)", "Label Query", "Replicas"}
var serviceColumns = []string{"Name", "Label Query", "Port"}
var serviceColumns = []string{"Name", "Labels", "Selector", "Port"}
func (h *HumanReadablePrinter) unknown(data string, w io.Writer) error {
_, err := fmt.Fprintf(w, "Unknown object: %s", data)
@ -89,17 +90,9 @@ func (h *HumanReadablePrinter) makeImageList(manifest api.ContainerManifest) str
return strings.Join(images, ",")
}
func (h *HumanReadablePrinter) makeLabelsList(labels map[string]string) string {
var vals []string
for key, value := range labels {
vals = append(vals, fmt.Sprintf("%s=%s", key, value))
}
return strings.Join(vals, ",")
}
func (h *HumanReadablePrinter) printPod(pod api.Pod, w io.Writer) error {
_, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\n",
pod.ID, h.makeImageList(pod.DesiredState.Manifest), pod.CurrentState.Host+"/"+pod.CurrentState.HostIP, h.makeLabelsList(pod.Labels))
pod.ID, h.makeImageList(pod.DesiredState.Manifest), pod.CurrentState.Host+"/"+pod.CurrentState.HostIP, labels.Set(pod.Labels))
return err
}
@ -114,7 +107,7 @@ func (h *HumanReadablePrinter) printPodList(podList api.PodList, w io.Writer) er
func (h *HumanReadablePrinter) printReplicationController(ctrl api.ReplicationController, w io.Writer) error {
_, err := fmt.Fprintf(w, "%s\t%s\t%s\t%d\n",
ctrl.ID, h.makeImageList(ctrl.DesiredState.PodTemplate.DesiredState.Manifest), h.makeLabelsList(ctrl.DesiredState.ReplicasInSet), ctrl.DesiredState.Replicas)
ctrl.ID, h.makeImageList(ctrl.DesiredState.PodTemplate.DesiredState.Manifest), labels.Set(ctrl.DesiredState.ReplicasInSet), ctrl.DesiredState.Replicas)
return err
}
@ -128,7 +121,7 @@ func (h *HumanReadablePrinter) printReplicationControllerList(list api.Replicati
}
func (h *HumanReadablePrinter) printService(svc api.Service, w io.Writer) error {
_, err := fmt.Fprintf(w, "%s\t%s\t%d\n", svc.ID, h.makeLabelsList(svc.Labels), svc.Port)
_, err := fmt.Fprintf(w, "%s\t%s\t%s\t%d\n", svc.ID, labels.Set(svc.Labels), labels.Set(svc.Selector), svc.Port)
return err
}

View File

@ -45,3 +45,8 @@ func (ls Set) String() string {
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)
}

View File

@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package registry
import (
@ -42,7 +43,7 @@ func (e *EndpointController) SyncServiceEndpoints() error {
}
var resultErr error
for _, service := range services.Items {
pods, err := e.podRegistry.ListPods(labels.QueryFromSet(labels.Set(service.Labels)))
pods, err := e.podRegistry.ListPods(labels.Set(service.Selector).AsQuery())
if err != nil {
log.Printf("Error syncing service: %#v, skipping.", service)
resultErr = err

View File

@ -49,7 +49,7 @@ func TestSyncEndpointsItems(t *testing.T) {
list: api.ServiceList{
Items: []api.Service{
{
Labels: map[string]string{
Selector: map[string]string{
"foo": "bar",
},
},
@ -92,7 +92,7 @@ func TestSyncEndpointsPodError(t *testing.T) {
list: api.ServiceList{
Items: []api.Service{
{
Labels: map[string]string{
Selector: map[string]string{
"foo": "bar",
},
},

View File

@ -604,16 +604,21 @@ func TestEtcdUpdateService(t *testing.T) {
fakeClient := util.MakeFakeEtcdClient(t)
fakeClient.Set("/registry/services/specs/foo", util.MakeJSONString(api.Service{JSONBase: api.JSONBase{ID: "foo"}}), 0)
registry := MakeTestEtcdRegistry(fakeClient, []string{"machine"})
err := registry.UpdateService(api.Service{
testService := api.Service{
JSONBase: api.JSONBase{ID: "foo"},
Labels: map[string]string{
"baz": "bar",
},
})
Selector: map[string]string{
"baz": "bar",
},
}
err := registry.UpdateService(testService)
expectNoError(t, err)
svc, err := registry.GetService("foo")
if svc.Labels["baz"] != "bar" {
t.Errorf("Unexpected service: %#v", svc)
expectNoError(t, err)
if !reflect.DeepEqual(*svc, testService) {
t.Errorf("Unexpected service: got %#v, wanted %#v", svc, testService)
}
}