mirror of https://github.com/k3s-io/k3s
Move service enviroment vars code.
GetServiceEnvironmentVariables (originally in pkg/registry/service/rest.go) is split into two parts: one that lists services, and one that turns a ServiceList into environment vars. This will allow a subsequent PR to add a call to the latter function with an existing ServiceList. The former part is moved into pkg/registry/pod/bound_pod_factory.go. The latter part is put in a new package, pkg/kubelet/envvars/envvars.go. The new package is under kubelet because the container enviroment is more associated with kubelet than with registry. Test code moved too.pull/6/head
parent
162e4983b9
commit
f122fc94bf
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
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 envvars is the package that build the environment variables that kubernetes provides
|
||||
// to the containers run by it.
|
||||
package envvars
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
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 envvars
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
// FromServices builds environment variables that a container is started with,
|
||||
// which tell the container where to find the services it may need, which are
|
||||
// provided as an argument.
|
||||
func FromServices(services *api.ServiceList) []api.EnvVar {
|
||||
var result []api.EnvVar
|
||||
for _, service := range services.Items {
|
||||
// Host
|
||||
name := makeEnvVariableName(service.Name) + "_SERVICE_HOST"
|
||||
result = append(result, api.EnvVar{Name: name, Value: service.Spec.PortalIP})
|
||||
// Port
|
||||
name = makeEnvVariableName(service.Name) + "_SERVICE_PORT"
|
||||
result = append(result, api.EnvVar{Name: name, Value: strconv.Itoa(service.Spec.Port)})
|
||||
// Docker-compatible vars.
|
||||
result = append(result, makeLinkVariables(service)...)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func makeEnvVariableName(str string) string {
|
||||
return strings.ToUpper(strings.Replace(str, "-", "_", -1))
|
||||
}
|
||||
|
||||
func makeLinkVariables(service api.Service) []api.EnvVar {
|
||||
prefix := makeEnvVariableName(service.Name)
|
||||
protocol := string(api.ProtocolTCP)
|
||||
if service.Spec.Protocol != "" {
|
||||
protocol = string(service.Spec.Protocol)
|
||||
}
|
||||
portPrefix := fmt.Sprintf("%s_PORT_%d_%s", prefix, service.Spec.Port, strings.ToUpper(protocol))
|
||||
return []api.EnvVar{
|
||||
{
|
||||
Name: prefix + "_PORT",
|
||||
Value: fmt.Sprintf("%s://%s:%d", strings.ToLower(protocol), service.Spec.PortalIP, service.Spec.Port),
|
||||
},
|
||||
{
|
||||
Name: portPrefix,
|
||||
Value: fmt.Sprintf("%s://%s:%d", strings.ToLower(protocol), service.Spec.PortalIP, service.Spec.Port),
|
||||
},
|
||||
{
|
||||
Name: portPrefix + "_PROTO",
|
||||
Value: strings.ToLower(protocol),
|
||||
},
|
||||
{
|
||||
Name: portPrefix + "_PORT",
|
||||
Value: strconv.Itoa(service.Spec.Port),
|
||||
},
|
||||
{
|
||||
Name: portPrefix + "_ADDR",
|
||||
Value: service.Spec.PortalIP,
|
||||
},
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
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 envvars_test
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/envvars"
|
||||
)
|
||||
|
||||
func TestFromServices(t *testing.T) {
|
||||
sl := api.ServiceList{
|
||||
Items: []api.Service{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo-bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8080,
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Protocol: "TCP",
|
||||
PortalIP: "1.2.3.4",
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc-123"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8081,
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Protocol: "UDP",
|
||||
PortalIP: "5.6.7.8",
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "q-u-u-x"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8082,
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Protocol: "TCP",
|
||||
PortalIP: "9.8.7.6",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
vars := envvars.FromServices(&sl)
|
||||
expected := []api.EnvVar{
|
||||
{Name: "FOO_BAR_SERVICE_HOST", Value: "1.2.3.4"},
|
||||
{Name: "FOO_BAR_SERVICE_PORT", Value: "8080"},
|
||||
{Name: "FOO_BAR_PORT", Value: "tcp://1.2.3.4:8080"},
|
||||
{Name: "FOO_BAR_PORT_8080_TCP", Value: "tcp://1.2.3.4:8080"},
|
||||
{Name: "FOO_BAR_PORT_8080_TCP_PROTO", Value: "tcp"},
|
||||
{Name: "FOO_BAR_PORT_8080_TCP_PORT", Value: "8080"},
|
||||
{Name: "FOO_BAR_PORT_8080_TCP_ADDR", Value: "1.2.3.4"},
|
||||
{Name: "ABC_123_SERVICE_HOST", Value: "5.6.7.8"},
|
||||
{Name: "ABC_123_SERVICE_PORT", Value: "8081"},
|
||||
{Name: "ABC_123_PORT", Value: "udp://5.6.7.8:8081"},
|
||||
{Name: "ABC_123_PORT_8081_UDP", Value: "udp://5.6.7.8:8081"},
|
||||
{Name: "ABC_123_PORT_8081_UDP_PROTO", Value: "udp"},
|
||||
{Name: "ABC_123_PORT_8081_UDP_PORT", Value: "8081"},
|
||||
{Name: "ABC_123_PORT_8081_UDP_ADDR", Value: "5.6.7.8"},
|
||||
{Name: "Q_U_U_X_SERVICE_HOST", Value: "9.8.7.6"},
|
||||
{Name: "Q_U_U_X_SERVICE_PORT", Value: "8082"},
|
||||
{Name: "Q_U_U_X_PORT", Value: "tcp://9.8.7.6:8082"},
|
||||
{Name: "Q_U_U_X_PORT_8082_TCP", Value: "tcp://9.8.7.6:8082"},
|
||||
{Name: "Q_U_U_X_PORT_8082_TCP_PROTO", Value: "tcp"},
|
||||
{Name: "Q_U_U_X_PORT_8082_TCP_PORT", Value: "8082"},
|
||||
{Name: "Q_U_U_X_PORT_8082_TCP_ADDR", Value: "9.8.7.6"},
|
||||
}
|
||||
if len(vars) != len(expected) {
|
||||
t.Errorf("Expected %d env vars, got: %+v", len(expected), vars)
|
||||
return
|
||||
}
|
||||
for i := range expected {
|
||||
if !reflect.DeepEqual(vars[i], expected[i]) {
|
||||
t.Errorf("expected %#v, got %#v", vars[i], expected[i])
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ package pod
|
|||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/envvars"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service"
|
||||
)
|
||||
|
||||
|
@ -31,8 +32,19 @@ type BasicBoundPodFactory struct {
|
|||
ServiceRegistry service.Registry
|
||||
}
|
||||
|
||||
// getServiceEnvironmentVariables populates a list of environment variables that are use
|
||||
// in the container environment to get access to services.
|
||||
func getServiceEnvironmentVariables(ctx api.Context, registry service.Registry, machine string) ([]api.EnvVar, error) {
|
||||
var result []api.EnvVar
|
||||
services, err := registry.ListServices(ctx)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
return envvars.FromServices(services), nil
|
||||
}
|
||||
|
||||
func (b *BasicBoundPodFactory) MakeBoundPod(machine string, pod *api.Pod) (*api.BoundPod, error) {
|
||||
envVars, err := service.GetServiceEnvironmentVariables(api.NewContext(), b.ServiceRegistry, machine)
|
||||
envVars, err := getServiceEnvironmentVariables(api.NewContext(), b.ServiceRegistry, machine)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -44,8 +56,6 @@ func (b *BasicBoundPodFactory) MakeBoundPod(machine string, pod *api.Pod) (*api.
|
|||
boundPod.Spec.Containers[ix].Env = append(container.Env, envVars...)
|
||||
}
|
||||
// Make a dummy self link so that references to this bound pod will work.
|
||||
// TODO: When kubelets get boundPods from apiserver instead of etcd, then
|
||||
// the selflink should be generated there.
|
||||
boundPod.SelfLink = "/api/v1beta1/boundPods/" + boundPod.Name
|
||||
return boundPod, nil
|
||||
}
|
||||
|
|
|
@ -20,8 +20,6 @@ import (
|
|||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
|
||||
|
@ -211,27 +209,6 @@ func (*REST) New() runtime.Object {
|
|||
return &api.Service{}
|
||||
}
|
||||
|
||||
// GetServiceEnvironmentVariables populates a list of environment variables that are use
|
||||
// in the container environment to get access to services.
|
||||
func GetServiceEnvironmentVariables(ctx api.Context, registry Registry, machine string) ([]api.EnvVar, error) {
|
||||
var result []api.EnvVar
|
||||
services, err := registry.ListServices(ctx)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
for _, service := range services.Items {
|
||||
// Host
|
||||
name := makeEnvVariableName(service.Name) + "_SERVICE_HOST"
|
||||
result = append(result, api.EnvVar{Name: name, Value: service.Spec.PortalIP})
|
||||
// Port
|
||||
name = makeEnvVariableName(service.Name) + "_SERVICE_PORT"
|
||||
result = append(result, api.EnvVar{Name: name, Value: strconv.Itoa(service.Spec.Port)})
|
||||
// Docker-compatible vars.
|
||||
result = append(result, makeLinkVariables(service)...)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (rs *REST) Update(ctx api.Context, obj runtime.Object) (<-chan apiserver.RESTResult, error) {
|
||||
service := obj.(*api.Service)
|
||||
if !api.ValidNamespace(ctx, &service.ObjectMeta) {
|
||||
|
@ -300,38 +277,3 @@ func (rs *REST) deleteExternalLoadBalancer(service *api.Service) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeEnvVariableName(str string) string {
|
||||
return strings.ToUpper(strings.Replace(str, "-", "_", -1))
|
||||
}
|
||||
|
||||
func makeLinkVariables(service api.Service) []api.EnvVar {
|
||||
prefix := makeEnvVariableName(service.Name)
|
||||
protocol := string(api.ProtocolTCP)
|
||||
if service.Spec.Protocol != "" {
|
||||
protocol = string(service.Spec.Protocol)
|
||||
}
|
||||
portPrefix := fmt.Sprintf("%s_PORT_%d_%s", prefix, service.Spec.Port, strings.ToUpper(protocol))
|
||||
return []api.EnvVar{
|
||||
{
|
||||
Name: prefix + "_PORT",
|
||||
Value: fmt.Sprintf("%s://%s:%d", strings.ToLower(protocol), service.Spec.PortalIP, service.Spec.Port),
|
||||
},
|
||||
{
|
||||
Name: portPrefix,
|
||||
Value: fmt.Sprintf("%s://%s:%d", strings.ToLower(protocol), service.Spec.PortalIP, service.Spec.Port),
|
||||
},
|
||||
{
|
||||
Name: portPrefix + "_PROTO",
|
||||
Value: strings.ToLower(protocol),
|
||||
},
|
||||
{
|
||||
Name: portPrefix + "_PORT",
|
||||
Value: strconv.Itoa(service.Spec.Port),
|
||||
},
|
||||
{
|
||||
Name: portPrefix + "_ADDR",
|
||||
Value: service.Spec.PortalIP,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ package service
|
|||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
@ -288,79 +287,6 @@ func TestServiceRegistryDeleteExternal(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestServiceRegistryMakeLinkVariables(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
registry := registrytest.NewServiceRegistry()
|
||||
registry.List = api.ServiceList{
|
||||
Items: []api.Service{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo-bar"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8080,
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Protocol: "TCP",
|
||||
PortalIP: "1.2.3.4",
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "abc-123"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8081,
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Protocol: "UDP",
|
||||
PortalIP: "5.6.7.8",
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "q-u-u-x"},
|
||||
Spec: api.ServiceSpec{
|
||||
Port: 8082,
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
Protocol: "TCP",
|
||||
PortalIP: "9.8.7.6",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
machine := "machine"
|
||||
vars, err := GetServiceEnvironmentVariables(ctx, registry, machine)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected err: %v", err)
|
||||
}
|
||||
expected := []api.EnvVar{
|
||||
{Name: "FOO_BAR_SERVICE_HOST", Value: "1.2.3.4"},
|
||||
{Name: "FOO_BAR_SERVICE_PORT", Value: "8080"},
|
||||
{Name: "FOO_BAR_PORT", Value: "tcp://1.2.3.4:8080"},
|
||||
{Name: "FOO_BAR_PORT_8080_TCP", Value: "tcp://1.2.3.4:8080"},
|
||||
{Name: "FOO_BAR_PORT_8080_TCP_PROTO", Value: "tcp"},
|
||||
{Name: "FOO_BAR_PORT_8080_TCP_PORT", Value: "8080"},
|
||||
{Name: "FOO_BAR_PORT_8080_TCP_ADDR", Value: "1.2.3.4"},
|
||||
{Name: "ABC_123_SERVICE_HOST", Value: "5.6.7.8"},
|
||||
{Name: "ABC_123_SERVICE_PORT", Value: "8081"},
|
||||
{Name: "ABC_123_PORT", Value: "udp://5.6.7.8:8081"},
|
||||
{Name: "ABC_123_PORT_8081_UDP", Value: "udp://5.6.7.8:8081"},
|
||||
{Name: "ABC_123_PORT_8081_UDP_PROTO", Value: "udp"},
|
||||
{Name: "ABC_123_PORT_8081_UDP_PORT", Value: "8081"},
|
||||
{Name: "ABC_123_PORT_8081_UDP_ADDR", Value: "5.6.7.8"},
|
||||
{Name: "Q_U_U_X_SERVICE_HOST", Value: "9.8.7.6"},
|
||||
{Name: "Q_U_U_X_SERVICE_PORT", Value: "8082"},
|
||||
{Name: "Q_U_U_X_PORT", Value: "tcp://9.8.7.6:8082"},
|
||||
{Name: "Q_U_U_X_PORT_8082_TCP", Value: "tcp://9.8.7.6:8082"},
|
||||
{Name: "Q_U_U_X_PORT_8082_TCP_PROTO", Value: "tcp"},
|
||||
{Name: "Q_U_U_X_PORT_8082_TCP_PORT", Value: "8082"},
|
||||
{Name: "Q_U_U_X_PORT_8082_TCP_ADDR", Value: "9.8.7.6"},
|
||||
}
|
||||
if len(vars) != len(expected) {
|
||||
t.Errorf("Expected %d env vars, got: %+v", len(expected), vars)
|
||||
return
|
||||
}
|
||||
for i := range expected {
|
||||
if !reflect.DeepEqual(vars[i], expected[i]) {
|
||||
t.Errorf("expected %#v, got %#v", vars[i], expected[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestServiceRegistryGet(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
registry := registrytest.NewServiceRegistry()
|
||||
|
|
Loading…
Reference in New Issue