未验证 提交 fcc9bf45 编写于 作者: A Alessandro (Ale) Segala 提交者: GitHub

Inject APP_PROTOCOL in app containers (#6512)

Signed-off-by: NItalyPaleAle <43508+ItalyPaleAle@users.noreply.github.com>
Co-authored-by: NYaron Schneider <schneider.yaron@live.com>
上级 041c1008
......@@ -17,6 +17,7 @@ import (
"context"
"encoding/json"
"fmt"
"strings"
v1 "k8s.io/api/admission/v1"
corev1 "k8s.io/api/core/v1"
......@@ -147,7 +148,7 @@ func (i *injector) getPodPatchOperations(ctx context.Context, ar *v1.AdmissionRe
sidecar.AddDaprSideCarMetricsEnabledLabel(metricsEnabled, pod.Labels))
patchOps = append(patchOps,
sidecar.AddDaprEnvVarsToContainers(appContainers)...)
sidecar.AddDaprEnvVarsToContainers(appContainers, getAppProtocol(an))...)
patchOps = append(patchOps,
sidecar.AddSocketVolumeMountToContainers(appContainers, socketVolumeMount)...)
volumePatchOps := sidecar.GetVolumesPatchOperations(
......@@ -176,3 +177,33 @@ func mTLSEnabled(daprClient scheme.Interface) bool {
log.Infof("Dapr system configuration (%s) is not found, use default value %t for mTLSEnabled", defaultConfig, defaultMtlsEnabled)
return defaultMtlsEnabled
}
func getAppProtocol(an annotations.Map) string {
appProtocol := strings.ToLower(an.GetString(annotations.KeyAppProtocol))
appSSL := an.GetBoolOrDefault(annotations.KeyAppSSL, annotations.DefaultAppSSL)
switch appProtocol {
case string(sidecar.GRPCSProtocol), string(sidecar.HTTPSProtocol), string(sidecar.H2CProtocol):
return appProtocol
case string(sidecar.HTTPProtocol):
// For backwards compatibility, when protocol is HTTP and --app-ssl is set, use "https"
// TODO: Remove in a future Dapr version
if appSSL {
return string(sidecar.HTTPSProtocol)
} else {
return string(sidecar.HTTPProtocol)
}
case string(sidecar.GRPCProtocol):
// For backwards compatibility, when protocol is GRPC and --app-ssl is set, use "grpcs"
// TODO: Remove in a future Dapr version
if appSSL {
return string(sidecar.GRPCSProtocol)
} else {
return string(sidecar.GRPCProtocol)
}
case "":
return string(sidecar.HTTPProtocol)
default:
return ""
}
}
......@@ -31,9 +31,16 @@ const (
SidecarMetricsEnabledLabel = "dapr.io/metrics-enabled"
APIVersionV1 = "v1.0"
UnixDomainSocketVolume = "dapr-unix-domain-socket" // Name of the Unix domain socket volume.
UserContainerAppProtocolName = "APP_PROTOCOL" // Name of the variable exposed to the app containing the app protocol.
UserContainerDaprHTTPPortName = "DAPR_HTTP_PORT" // Name of the variable exposed to the app containing the Dapr HTTP port.
UserContainerDaprGRPCPortName = "DAPR_GRPC_PORT" // Name of the variable exposed to the app containing the Dapr gRPC port.
PatchPathLabels = "/metadata/labels"
TokenVolumeKubernetesMountPath = "/var/run/secrets/dapr.io/sentrytoken" /* #nosec */ // Mount path for the Kubernetes service account volume with the sentry token.
TokenVolumeName = "dapr-identity-token" /* #nosec */ // Name of the volume with the service account token for daprd.
GRPCProtocol = "grpc" // GRPCProtocol is the gRPC communication protocol.
GRPCSProtocol = "grpcs" // GRPCSProtocol is the gRPC communication protocol with TLS (without validating certificates).
HTTPProtocol = "http" // HTTPProtocol is the HTTP communication protocol.
HTTPSProtocol = "https" // HTTPSProtocol is the HTTPS communication protocol with TLS (without validating certificates).
H2CProtocol = "h2c" // H2CProtocol is the HTTP/2 Cleartext communication protocol (HTTP/2 without TLS).
)
......@@ -28,24 +28,28 @@ import (
"github.com/dapr/kit/ptr"
)
// DaprPortEnv contains the env vars that are set in containers to pass the ports used by Dapr.
var DaprPortEnv = []corev1.EnvVar{
{
Name: UserContainerDaprHTTPPortName,
Value: strconv.Itoa(SidecarHTTPPort),
},
{
Name: UserContainerDaprGRPCPortName,
Value: strconv.Itoa(SidecarAPIGRPCPort),
},
}
// AddDaprEnvVarsToContainers adds Dapr environment variables to all the containers in any Dapr-enabled pod.
// The containers can be injected or user-defined.
func AddDaprEnvVarsToContainers(containers map[int]corev1.Container) []patcher.PatchOperation {
func AddDaprEnvVarsToContainers(containers map[int]corev1.Container, appProtocol string) []patcher.PatchOperation {
envPatchOps := make([]patcher.PatchOperation, 0, len(containers))
envVars := []corev1.EnvVar{
{
Name: UserContainerDaprHTTPPortName,
Value: strconv.Itoa(SidecarHTTPPort),
},
{
Name: UserContainerDaprGRPCPortName,
Value: strconv.Itoa(SidecarAPIGRPCPort),
},
}
if appProtocol != "" {
envVars = append(envVars, corev1.EnvVar{
Name: UserContainerAppProtocolName,
Value: appProtocol,
})
}
for i, container := range containers {
patchOps := patcher.GetEnvPatchOperations(container.Env, DaprPortEnv, i)
patchOps := patcher.GetEnvPatchOperations(container.Env, envVars, i)
envPatchOps = append(envPatchOps, patchOps...)
}
return envPatchOps
......@@ -124,17 +128,6 @@ func addVolumeMountToContainers(containers map[int]corev1.Container, addMounts c
return volumeMountPatchOps
}
// AddServiceAccountTokenVolume adds the projected volume for the service account token to the daprd
// The containers can be injected or user-defined.
func AddServiceAccountTokenVolume(containers []corev1.Container) []patcher.PatchOperation {
envPatchOps := make([]patcher.PatchOperation, 0, len(containers))
for i, container := range containers {
patchOps := patcher.GetEnvPatchOperations(container.Env, DaprPortEnv, i)
envPatchOps = append(envPatchOps, patchOps...)
}
return envPatchOps
}
func GetVolumesPatchOperations(volumes []corev1.Volume, addVolumes []corev1.Volume, path string) []patcher.PatchOperation {
if len(volumes) == 0 {
// If there are no volumes defined in the container, we initialize a slice of volumes.
......
......@@ -31,6 +31,7 @@ func TestAddDaprEnvVarsToContainers(t *testing.T) {
testCases := []struct {
testName string
mockContainer coreV1.Container
appProtocol string
expOpsLen int
expOps []patcher.PatchOperation
}{
......@@ -133,12 +134,39 @@ func TestAddDaprEnvVarsToContainers(t *testing.T) {
expOpsLen: 0,
expOps: []patcher.PatchOperation{},
},
{
testName: "with app protocol",
mockContainer: coreV1.Container{
Name: "MockContainer",
},
expOpsLen: 1,
appProtocol: "h2c",
expOps: []patcher.PatchOperation{
{
Op: "add",
Path: "/spec/containers/0/env",
Value: []coreV1.EnvVar{
{
Name: UserContainerDaprHTTPPortName,
Value: strconv.Itoa(SidecarHTTPPort),
},
{
Name: UserContainerDaprGRPCPortName,
Value: strconv.Itoa(SidecarAPIGRPCPort),
},
{
Name: UserContainerAppProtocolName,
Value: "h2c",
},
},
},
},
},
}
for _, tc := range testCases {
tc := tc
t.Run(tc.testName, func(t *testing.T) {
patchEnv := AddDaprEnvVarsToContainers(map[int]coreV1.Container{0: tc.mockContainer})
patchEnv := AddDaprEnvVarsToContainers(map[int]coreV1.Container{0: tc.mockContainer}, tc.appProtocol)
assert.Equal(t, tc.expOpsLen, len(patchEnv))
assert.Equal(t, tc.expOps, patchEnv)
})
......
......@@ -72,6 +72,11 @@ func main() {
appProtocol = os.Getenv("APP_PROTOCOL")
expectAppProtocol := os.Getenv("EXPECT_APP_PROTOCOL")
if expectAppProtocol != "" && appProtocol != expectAppProtocol {
log.Fatalf("Expected injected APP_PROTOCOL to be %q, but got %q", expectAppProtocol, appProtocol)
}
controlPort = os.Getenv("CONTROL_PORT")
if controlPort == "" {
controlPort = "3000"
......
......@@ -65,9 +65,9 @@ func TestMain(m *testing.M) {
AppHealthProbeTimeout: 200,
AppHealthThreshold: 3,
AppEnv: map[string]string{
"APP_PROTOCOL": "http",
"APP_PORT": "4000",
"CONTROL_PORT": "3000",
"APP_PORT": "4000",
"CONTROL_PORT": "3000",
"EXPECT_APP_PROTOCOL": "http",
},
},
{
......@@ -86,9 +86,9 @@ func TestMain(m *testing.M) {
AppHealthProbeTimeout: 200,
AppHealthThreshold: 3,
AppEnv: map[string]string{
"APP_PROTOCOL": "grpc",
"APP_PORT": "4000",
"CONTROL_PORT": "3000",
"APP_PORT": "4000",
"CONTROL_PORT": "3000",
"EXPECT_APP_PROTOCOL": "grpc",
},
},
{
......@@ -107,9 +107,9 @@ func TestMain(m *testing.M) {
AppHealthProbeTimeout: 200,
AppHealthThreshold: 3,
AppEnv: map[string]string{
"APP_PROTOCOL": "h2c",
"APP_PORT": "4000",
"CONTROL_PORT": "3000",
"APP_PORT": "4000",
"CONTROL_PORT": "3000",
"EXPECT_APP_PROTOCOL": "h2c",
},
},
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册