pkg/inject/proxy.go (100 lines of code) (raw):
package inject
import (
"fmt"
"strings"
appmesh "github.com/aws/aws-app-mesh-controller-for-k8s/apis/appmesh/v1beta2"
corev1 "k8s.io/api/core/v1"
)
const (
defaultProxyEgressPort = 15001
defaultProxyIngressPort = 15000
defaultProxyUID = 1337
defaultEgressIgnoredPorts = "22"
)
type proxyMutatorConfig struct {
initProxyMutatorConfig
egressIgnoredIPs string
}
func newProxyMutator(mutatorConfig proxyMutatorConfig, vn *appmesh.VirtualNode) *proxyMutator {
return &proxyMutator{
mutatorConfig: mutatorConfig,
vn: vn,
}
}
type proxyMutator struct {
mutatorConfig proxyMutatorConfig
vn *appmesh.VirtualNode
}
func (m *proxyMutator) mutate(pod *corev1.Pod) error {
proxyConfig := m.buildProxyConfig(pod)
var mutator PodMutator
if m.isAppMeshCNIEnabled(pod) {
mutator = newCNIProxyMutator(proxyConfig)
} else {
mutator = newInitProxyMutator(m.mutatorConfig.initProxyMutatorConfig, proxyConfig)
}
return mutator.mutate(pod)
}
type proxyConfig struct {
// Ports that needs to intercepting ingress traffic
appPorts string
// IPs that need to be ignored when intercepting traffic
egressIgnoredIPs string
// Ports that need to ignored when intercepting traffic
egressIgnoredPorts string
// port used by proxy for egress traffic (traffic originating from app container to external services)
proxyEgressPort int64
// port used by proxy for incoming traffic
proxyIngressPort int64
// UID used by proxy
proxyUID int64
// Whether or not to enable ipv6. *bool required instead of bool because when enableIPV6 is not set explicitly its zero value is false resulting in unexpected value of APPMESH_ENABLE_IPV6=0 in the proxyinit env vars.
enableIPV6 *bool
}
func (m *proxyMutator) buildProxyConfig(pod *corev1.Pod) proxyConfig {
appPorts := m.getAppPorts(pod)
egressIgnoredPorts := m.getEgressIgnoredPorts(pod)
enableIPV6 := m.isIPV6Enabled(pod)
return proxyConfig{
appPorts: appPorts,
egressIgnoredIPs: m.mutatorConfig.egressIgnoredIPs,
egressIgnoredPorts: egressIgnoredPorts,
proxyEgressPort: defaultProxyEgressPort,
proxyIngressPort: defaultProxyIngressPort,
proxyUID: defaultProxyUID,
enableIPV6: &enableIPV6,
}
}
func (m *proxyMutator) getAppPorts(pod *corev1.Pod) string {
if v, ok := pod.ObjectMeta.Annotations[AppMeshPortsAnnotation]; ok {
return v
}
var ports []string
for _, listener := range m.vn.Spec.Listeners {
ports = append(ports, fmt.Sprintf("%d", listener.PortMapping.Port))
}
if len(ports) == 0 {
// return empty string when there are no listener ports
return ""
}
return strings.Join(ports, ",")
}
func (m *proxyMutator) getEgressIgnoredPorts(pod *corev1.Pod) string {
egressIgnoredPorts := defaultEgressIgnoredPorts
if v, ok := pod.ObjectMeta.Annotations[AppMeshEgressIgnoredPortsAnnotation]; ok {
egressIgnoredPorts = v
}
return egressIgnoredPorts
}
func (m *proxyMutator) isAppMeshCNIEnabled(pod *corev1.Pod) bool {
annotations := pod.GetAnnotations()
if v, ok := annotations[AppMeshCNIAnnotation]; ok {
return strings.ToLower(v) == "enabled"
}
// Fargate platform has appMesh-cni enabled by default
if v, ok := pod.GetLabels()[FargateProfileLabel]; ok {
return len(v) > 0
}
return false
}
func (m *proxyMutator) isIPV6Enabled(pod *corev1.Pod) bool {
annotations := pod.GetAnnotations()
if v, ok := annotations[AppMeshIPV6Annotation]; ok {
if v == "disabled" {
return false
}
envoyUtilsLogger.Info("Unsupported Value. Annotation only accepts `disabled` in the value field. ", "Value Provided: ", v)
}
return true
}