From 0e798bcc3cfab14e6eb6e2bd9071075936fb6d15 Mon Sep 17 00:00:00 2001 From: Brendan Burns Date: Sat, 12 Jul 2014 21:46:01 -0700 Subject: [PATCH] Add link env vars. --- pkg/api/types.go | 5 ++ pkg/registry/manifest_factory_test.go | 105 ++++++++++++++++++++++---- pkg/registry/service_registry.go | 35 +++++++++ 3 files changed, 131 insertions(+), 14 deletions(-) diff --git a/pkg/api/types.go b/pkg/api/types.go index 6bc42f34589..e6400b27733 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -18,6 +18,8 @@ package api import ( "github.com/fsouza/go-dockerclient" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) // Common string formats @@ -267,6 +269,9 @@ type Service struct { // 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"` + + // Container port to connect to, either a name or a port number + ContainerPort util.IntOrString `json:"containerPort,omitempty" yaml:"containerPort,omitempty"` } // Endpoints is a collection of endpoints that implement the actual service, for example: diff --git a/pkg/registry/manifest_factory_test.go b/pkg/registry/manifest_factory_test.go index a215106e437..05710d60424 100644 --- a/pkg/registry/manifest_factory_test.go +++ b/pkg/registry/manifest_factory_test.go @@ -17,9 +17,11 @@ limitations under the License. package registry import ( + "reflect" "testing" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) func TestMakeManifestNoServices(t *testing.T) { @@ -59,6 +61,10 @@ func TestMakeManifestServices(t *testing.T) { { JSONBase: api.JSONBase{ID: "test"}, Port: 8080, + ContainerPort: util.IntOrString{ + Kind: util.IntstrInt, + IntVal: 900, + }, }, }, }, @@ -80,12 +86,44 @@ func TestMakeManifestServices(t *testing.T) { }) expectNoError(t, err) container := manifest.Containers[0] - if len(container.Env) != 2 || - container.Env[0].Name != "TEST_SERVICE_PORT" || - container.Env[0].Value != "8080" || - container.Env[1].Name != "SERVICE_HOST" || - container.Env[1].Value != "machine" { - t.Errorf("Expected 2 env vars, got: %#v", manifest) + envs := []api.EnvVar{ + { + Name: "TEST_SERVICE_PORT", + Value: "8080", + }, + { + Name: "TEST_PORT", + Value: "tcp://machine:8080", + }, + { + Name: "TEST_PORT_900_TCP", + Value: "tcp://machine:8080", + }, + { + Name: "TEST_PORT_900_TCP_PROTO", + Value: "tcp", + }, + { + Name: "TEST_PORT_900_TCP_PORT", + Value: "8080", + }, + { + Name: "TEST_PORT_900_TCP_ADDR", + Value: "machine", + }, + { + Name: "SERVICE_HOST", + Value: "machine", + }, + } + if len(container.Env) != 7 { + t.Errorf("Expected 7 env vars, got %d: %#v", len(container.Env), manifest) + return + } + for ix := range container.Env { + if !reflect.DeepEqual(envs[ix], container.Env[ix]) { + t.Errorf("expected %#v, got %#v", envs[ix], container.Env[ix]) + } } } @@ -96,6 +134,10 @@ func TestMakeManifestServicesExistingEnvVar(t *testing.T) { { JSONBase: api.JSONBase{ID: "test"}, Port: 8080, + ContainerPort: util.IntOrString{ + Kind: util.IntstrInt, + IntVal: 900, + }, }, }, }, @@ -122,13 +164,48 @@ func TestMakeManifestServicesExistingEnvVar(t *testing.T) { }) expectNoError(t, err) container := manifest.Containers[0] - if len(container.Env) != 3 || - container.Env[0].Name != "foo" || - container.Env[0].Value != "bar" || - container.Env[1].Name != "TEST_SERVICE_PORT" || - container.Env[1].Value != "8080" || - container.Env[2].Name != "SERVICE_HOST" || - container.Env[2].Value != "machine" { - t.Errorf("Expected no env vars, got: %#v", manifest) + + envs := []api.EnvVar{ + { + Name: "foo", + Value: "bar", + }, + { + Name: "TEST_SERVICE_PORT", + Value: "8080", + }, + { + Name: "TEST_PORT", + Value: "tcp://machine:8080", + }, + { + Name: "TEST_PORT_900_TCP", + Value: "tcp://machine:8080", + }, + { + Name: "TEST_PORT_900_TCP_PROTO", + Value: "tcp", + }, + { + Name: "TEST_PORT_900_TCP_PORT", + Value: "8080", + }, + { + Name: "TEST_PORT_900_TCP_ADDR", + Value: "machine", + }, + { + Name: "SERVICE_HOST", + Value: "machine", + }, + } + if len(container.Env) != 8 { + t.Errorf("Expected 8 env vars, got: %#v", manifest) + return + } + for ix := range container.Env { + if !reflect.DeepEqual(envs[ix], container.Env[ix]) { + t.Errorf("expected %#v, got %#v", envs[ix], container.Env[ix]) + } } } diff --git a/pkg/registry/service_registry.go b/pkg/registry/service_registry.go index 6d4e0d8fd4d..70f8bb75f51 100644 --- a/pkg/registry/service_registry.go +++ b/pkg/registry/service_registry.go @@ -25,6 +25,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" ) type ServiceRegistryStorage struct { @@ -41,6 +42,39 @@ func MakeServiceRegistryStorage(registry ServiceRegistry, cloud cloudprovider.In } } +func makeLinkVariables(service api.Service, machine string) []api.EnvVar { + prefix := strings.ToUpper(service.ID) + var port string + if service.ContainerPort.Kind == util.IntstrString { + port = service.ContainerPort.StrVal + } else { + port = strconv.Itoa(service.ContainerPort.IntVal) + } + portPrefix := prefix + "_PORT_" + port + "_TCP" + return []api.EnvVar{ + { + Name: prefix + "_PORT", + Value: fmt.Sprintf("tcp://%s:%d", machine, service.Port), + }, + { + Name: portPrefix, + Value: fmt.Sprintf("tcp://%s:%d", machine, service.Port), + }, + { + Name: portPrefix + "_PROTO", + Value: "tcp", + }, + { + Name: portPrefix + "_PORT", + Value: strconv.Itoa(service.Port), + }, + { + Name: portPrefix + "_ADDR", + Value: machine, + }, + } +} + // GetServiceEnvironmentVariables populates a list of environment variables that are use // in the container environment to get access to services. func GetServiceEnvironmentVariables(registry ServiceRegistry, machine string) ([]api.EnvVar, error) { @@ -53,6 +87,7 @@ func GetServiceEnvironmentVariables(registry ServiceRegistry, machine string) ([ name := strings.ToUpper(service.ID) + "_SERVICE_PORT" value := strconv.Itoa(service.Port) result = append(result, api.EnvVar{Name: name, Value: value}) + result = append(result, makeLinkVariables(service, machine)...) } result = append(result, api.EnvVar{Name: "SERVICE_HOST", Value: machine}) return result, nil