mirror of
https://github.com/k3s-io/k3s.git
synced 2024-06-07 19:41:36 +00:00
114 lines
3.3 KiB
Go
114 lines
3.3 KiB
Go
/*
|
|
Copyright 2014 The Kubernetes Authors.
|
|
|
|
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"
|
|
"net"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"k8s.io/api/core/v1"
|
|
v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
|
|
)
|
|
|
|
// 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 []*v1.Service) []v1.EnvVar {
|
|
var result []v1.EnvVar
|
|
for i := range services {
|
|
service := services[i]
|
|
|
|
// ignore services where ClusterIP is "None" or empty
|
|
// the services passed to this method should be pre-filtered
|
|
// only services that have the cluster IP set should be included here
|
|
if !v1helper.IsServiceIPSet(service) {
|
|
continue
|
|
}
|
|
|
|
// Host
|
|
name := makeEnvVariableName(service.Name) + "_SERVICE_HOST"
|
|
result = append(result, v1.EnvVar{Name: name, Value: service.Spec.ClusterIP})
|
|
// First port - give it the backwards-compatible name
|
|
name = makeEnvVariableName(service.Name) + "_SERVICE_PORT"
|
|
result = append(result, v1.EnvVar{Name: name, Value: strconv.Itoa(int(service.Spec.Ports[0].Port))})
|
|
// All named ports (only the first may be unnamed, checked in validation)
|
|
for i := range service.Spec.Ports {
|
|
sp := &service.Spec.Ports[i]
|
|
if sp.Name != "" {
|
|
pn := name + "_" + makeEnvVariableName(sp.Name)
|
|
result = append(result, v1.EnvVar{Name: pn, Value: strconv.Itoa(int(sp.Port))})
|
|
}
|
|
}
|
|
// Docker-compatible vars.
|
|
result = append(result, makeLinkVariables(service)...)
|
|
}
|
|
return result
|
|
}
|
|
|
|
func makeEnvVariableName(str string) string {
|
|
// TODO: If we simplify to "all names are DNS1123Subdomains" this
|
|
// will need two tweaks:
|
|
// 1) Handle leading digits
|
|
// 2) Handle dots
|
|
return strings.ToUpper(strings.Replace(str, "-", "_", -1))
|
|
}
|
|
|
|
func makeLinkVariables(service *v1.Service) []v1.EnvVar {
|
|
prefix := makeEnvVariableName(service.Name)
|
|
all := []v1.EnvVar{}
|
|
for i := range service.Spec.Ports {
|
|
sp := &service.Spec.Ports[i]
|
|
|
|
protocol := string(v1.ProtocolTCP)
|
|
if sp.Protocol != "" {
|
|
protocol = string(sp.Protocol)
|
|
}
|
|
|
|
hostPort := net.JoinHostPort(service.Spec.ClusterIP, strconv.Itoa(int(sp.Port)))
|
|
|
|
if i == 0 {
|
|
// Docker special-cases the first port.
|
|
all = append(all, v1.EnvVar{
|
|
Name: prefix + "_PORT",
|
|
Value: fmt.Sprintf("%s://%s", strings.ToLower(protocol), hostPort),
|
|
})
|
|
}
|
|
portPrefix := fmt.Sprintf("%s_PORT_%d_%s", prefix, sp.Port, strings.ToUpper(protocol))
|
|
all = append(all, []v1.EnvVar{
|
|
{
|
|
Name: portPrefix,
|
|
Value: fmt.Sprintf("%s://%s", strings.ToLower(protocol), hostPort),
|
|
},
|
|
{
|
|
Name: portPrefix + "_PROTO",
|
|
Value: strings.ToLower(protocol),
|
|
},
|
|
{
|
|
Name: portPrefix + "_PORT",
|
|
Value: strconv.Itoa(int(sp.Port)),
|
|
},
|
|
{
|
|
Name: portPrefix + "_ADDR",
|
|
Value: service.Spec.ClusterIP,
|
|
},
|
|
}...)
|
|
}
|
|
return all
|
|
}
|