|
|
|
@ -163,6 +163,330 @@ type annotationPatch struct {
|
|
|
|
|
OpaquePorts string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AppendNamespaceAnnotations allows pods to inherit config specific annotations
|
|
|
|
|
// from the namespace they belong to. If the namespace has a valid config key
|
|
|
|
|
// that the pod does not, then it is appended to the pod's template
|
|
|
|
|
func AppendNamespaceAnnotations(base map[string]string, nsAnn map[string]string, workloadAnn map[string]string) {
|
|
|
|
|
ann := append(ProxyAnnotations, ProxyAlphaConfigAnnotations...)
|
|
|
|
|
ann = append(ann, k8s.ProxyInjectAnnotation)
|
|
|
|
|
|
|
|
|
|
for _, key := range ann {
|
|
|
|
|
if _, found := nsAnn[key]; !found {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if val, ok := GetConfigOverride(key, workloadAnn, nsAnn); ok {
|
|
|
|
|
base[key] = val
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetOverriddenValues returns the final Values struct which is created
|
|
|
|
|
// by overriding annotated configuration on top of default Values
|
|
|
|
|
func GetOverriddenValues(values *l5dcharts.Values, overrides map[string]string, namedPorts map[string]int32) (*l5dcharts.Values, error) {
|
|
|
|
|
// Make a copy of Values and mutate that
|
|
|
|
|
copyValues, err := values.DeepCopy()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
applyAnnotationOverrides(copyValues, overrides, namedPorts)
|
|
|
|
|
return copyValues, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func applyAnnotationOverrides(values *l5dcharts.Values, annotations map[string]string, namedPorts map[string]int32) {
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyInjectAnnotation]; ok {
|
|
|
|
|
if override == k8s.ProxyInjectIngress {
|
|
|
|
|
values.Proxy.IsIngress = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyImageAnnotation]; ok {
|
|
|
|
|
values.Proxy.Image.Name = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyVersionOverrideAnnotation]; ok {
|
|
|
|
|
values.Proxy.Image.Version = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyImagePullPolicyAnnotation]; ok {
|
|
|
|
|
values.Proxy.Image.PullPolicy = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyInitImageVersionAnnotation]; ok {
|
|
|
|
|
values.ProxyInit.Image.Version = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyControlPortAnnotation]; ok {
|
|
|
|
|
controlPort, err := strconv.ParseInt(override, 10, 32)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.Ports.Control = int32(controlPort)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyInboundPortAnnotation]; ok {
|
|
|
|
|
inboundPort, err := strconv.ParseInt(override, 10, 32)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.Ports.Inbound = int32(inboundPort)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyAdminPortAnnotation]; ok {
|
|
|
|
|
adminPort, err := strconv.ParseInt(override, 10, 32)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.Ports.Admin = int32(adminPort)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyOutboundPortAnnotation]; ok {
|
|
|
|
|
outboundPort, err := strconv.ParseInt(override, 10, 32)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.Ports.Outbound = int32(outboundPort)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyPodInboundPortsAnnotation]; ok {
|
|
|
|
|
values.Proxy.PodInboundPorts = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyLogLevelAnnotation]; ok {
|
|
|
|
|
values.Proxy.LogLevel = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyLogFormatAnnotation]; ok {
|
|
|
|
|
values.Proxy.LogFormat = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyRequireIdentityOnInboundPortsAnnotation]; ok {
|
|
|
|
|
values.Proxy.RequireIdentityOnInboundPorts = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyOutboundConnectTimeout]; ok {
|
|
|
|
|
duration, err := time.ParseDuration(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("unrecognized proxy-outbound-connect-timeout duration value found on pod annotation: %s", err.Error())
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.OutboundConnectTimeout = fmt.Sprintf("%dms", int(duration.Seconds()*1000))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyInboundConnectTimeout]; ok {
|
|
|
|
|
duration, err := time.ParseDuration(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("unrecognized proxy-inbound-connect-timeout duration value found on pod annotation: %s", err.Error())
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.InboundConnectTimeout = fmt.Sprintf("%dms", int(duration.Seconds()*1000))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyOutboundDiscoveryCacheUnusedTimeout]; ok {
|
|
|
|
|
duration, err := time.ParseDuration(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("unrecognized duration value used on pod annotation %s: %s", k8s.ProxyOutboundDiscoveryCacheUnusedTimeout, err.Error())
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.OutboundDiscoveryCacheUnusedTimeout = fmt.Sprintf("%ds", int(duration.Seconds()))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyInboundDiscoveryCacheUnusedTimeout]; ok {
|
|
|
|
|
duration, err := time.ParseDuration(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("unrecognized duration value used on pod annotation %s: %s", k8s.ProxyInboundDiscoveryCacheUnusedTimeout, err.Error())
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.InboundDiscoveryCacheUnusedTimeout = fmt.Sprintf("%ds", int(duration.Seconds()))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyDisableOutboundProtocolDetectTimeout]; ok {
|
|
|
|
|
value, err := strconv.ParseBool(override)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.DisableOutboundProtocolDetectTimeout = value
|
|
|
|
|
} else {
|
|
|
|
|
log.Warnf("unrecognised value used on pod annotation %s: %s", k8s.ProxyDisableOutboundProtocolDetectTimeout, err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyDisableInboundProtocolDetectTimeout]; ok {
|
|
|
|
|
value, err := strconv.ParseBool(override)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.DisableInboundProtocolDetectTimeout = value
|
|
|
|
|
} else {
|
|
|
|
|
log.Warnf("unrecognised value used on pod annotation %s: %s", k8s.ProxyDisableInboundProtocolDetectTimeout, err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyShutdownGracePeriodAnnotation]; ok {
|
|
|
|
|
duration, err := time.ParseDuration(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("unrecognized proxy-shutdown-grace-period duration value found on pod annotation: %s", err.Error())
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.ShutdownGracePeriod = fmt.Sprintf("%dms", int(duration.Seconds()*1000))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyEnableGatewayAnnotation]; ok {
|
|
|
|
|
value, err := strconv.ParseBool(override)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.IsGateway = value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyWaitBeforeExitSecondsAnnotation]; ok {
|
|
|
|
|
waitBeforeExitSeconds, err := strconv.ParseUint(override, 10, 64)
|
|
|
|
|
if nil != err {
|
|
|
|
|
log.Warnf("unrecognized value used for the %s annotation, uint64 is expected: %s",
|
|
|
|
|
k8s.ProxyWaitBeforeExitSecondsAnnotation, override)
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.WaitBeforeExitSeconds = waitBeforeExitSeconds
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyEnableNativeSidecarAnnotation]; ok {
|
|
|
|
|
value, err := strconv.ParseBool(override)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.NativeSidecar = value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyCPURequestAnnotation]; ok {
|
|
|
|
|
_, err := k8sResource.ParseQuantity(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("%s (%s)", err, k8s.ProxyCPURequestAnnotation)
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.Resources.CPU.Request = override
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyMemoryRequestAnnotation]; ok {
|
|
|
|
|
_, err := k8sResource.ParseQuantity(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("%s (%s)", err, k8s.ProxyMemoryRequestAnnotation)
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.Resources.Memory.Request = override
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyEphemeralStorageRequestAnnotation]; ok {
|
|
|
|
|
_, err := k8sResource.ParseQuantity(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("%s (%s)", err, k8s.ProxyEphemeralStorageRequestAnnotation)
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.Resources.EphemeralStorage.Request = override
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyCPULimitAnnotation]; ok {
|
|
|
|
|
q, err := k8sResource.ParseQuantity(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("%s (%s)", err, k8s.ProxyCPULimitAnnotation)
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.Resources.CPU.Limit = override
|
|
|
|
|
|
|
|
|
|
n, err := ToWholeCPUCores(q)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("%s (%s)", err, k8s.ProxyCPULimitAnnotation)
|
|
|
|
|
}
|
|
|
|
|
values.Proxy.Cores = n
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyMemoryLimitAnnotation]; ok {
|
|
|
|
|
_, err := k8sResource.ParseQuantity(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("%s (%s)", err, k8s.ProxyMemoryLimitAnnotation)
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.Resources.Memory.Limit = override
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyEphemeralStorageLimitAnnotation]; ok {
|
|
|
|
|
_, err := k8sResource.ParseQuantity(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("%s (%s)", err, k8s.ProxyEphemeralStorageLimitAnnotation)
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.Resources.EphemeralStorage.Limit = override
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyUIDAnnotation]; ok {
|
|
|
|
|
v, err := strconv.ParseInt(override, 10, 64)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.UID = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyEnableExternalProfilesAnnotation]; ok {
|
|
|
|
|
value, err := strconv.ParseBool(override)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.EnableExternalProfiles = value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyInitImageAnnotation]; ok {
|
|
|
|
|
values.ProxyInit.Image.Name = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyImagePullPolicyAnnotation]; ok {
|
|
|
|
|
values.ProxyInit.Image.PullPolicy = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyIgnoreInboundPortsAnnotation]; ok {
|
|
|
|
|
values.ProxyInit.IgnoreInboundPorts = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyIgnoreOutboundPortsAnnotation]; ok {
|
|
|
|
|
values.ProxyInit.IgnoreOutboundPorts = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyOpaquePortsAnnotation]; ok {
|
|
|
|
|
var opaquePorts strings.Builder
|
|
|
|
|
for _, pr := range util.ParseContainerOpaquePorts(override, namedPorts) {
|
|
|
|
|
if opaquePorts.Len() > 0 {
|
|
|
|
|
opaquePorts.WriteRune(',')
|
|
|
|
|
}
|
|
|
|
|
opaquePorts.WriteString(pr.ToString())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
values.Proxy.OpaquePorts = opaquePorts.String()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.DebugImageAnnotation]; ok {
|
|
|
|
|
values.DebugContainer.Image.Name = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.DebugImageVersionAnnotation]; ok {
|
|
|
|
|
values.DebugContainer.Image.Version = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.DebugImagePullPolicyAnnotation]; ok {
|
|
|
|
|
values.DebugContainer.Image.PullPolicy = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyAwait]; ok {
|
|
|
|
|
if override == k8s.Enabled || override == k8s.Disabled {
|
|
|
|
|
values.Proxy.Await = override == k8s.Enabled
|
|
|
|
|
} else {
|
|
|
|
|
log.Warnf("unrecognized value used for the %s annotation, valid values are: [%s, %s]", k8s.ProxyAwait, k8s.Enabled, k8s.Disabled)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyDefaultInboundPolicyAnnotation]; ok {
|
|
|
|
|
if override != k8s.AllUnauthenticated && override != k8s.AllAuthenticated && override != k8s.ClusterUnauthenticated && override != k8s.ClusterAuthenticated && override != k8s.Deny {
|
|
|
|
|
log.Warnf("unrecognized value used for the %s annotation, valid values are: [%s, %s, %s, %s, %s]", k8s.ProxyDefaultInboundPolicyAnnotation, k8s.AllUnauthenticated, k8s.AllAuthenticated, k8s.ClusterUnauthenticated, k8s.ClusterAuthenticated, k8s.Deny)
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.DefaultInboundPolicy = override
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxySkipSubnetsAnnotation]; ok {
|
|
|
|
|
values.ProxyInit.SkipSubnets = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyAccessLogAnnotation]; ok {
|
|
|
|
|
values.Proxy.AccessLog = override
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewResourceConfig creates and initializes a ResourceConfig
|
|
|
|
|
func NewResourceConfig(values *l5dcharts.Values, origin Origin, ns string) *ResourceConfig {
|
|
|
|
|
config := &ResourceConfig{
|
|
|
|
@ -205,21 +529,20 @@ func (conf *ResourceConfig) GetOwnerRef() *metav1.OwnerReference {
|
|
|
|
|
return conf.workload.ownerRef
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AppendNamespaceAnnotations allows pods to inherit config specific annotations
|
|
|
|
|
// from the namespace they belong to. If the namespace has a valid config key
|
|
|
|
|
// that the pod does not, then it is appended to the pod's template
|
|
|
|
|
func (conf *ResourceConfig) AppendNamespaceAnnotations() {
|
|
|
|
|
annotations := append(ProxyAnnotations, ProxyAlphaConfigAnnotations...)
|
|
|
|
|
annotations = append(annotations, k8s.ProxyInjectAnnotation)
|
|
|
|
|
func (conf *ResourceConfig) GetOverrideAnnotations() map[string]string {
|
|
|
|
|
return conf.pod.annotations
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, key := range annotations {
|
|
|
|
|
if _, found := conf.nsAnnotations[key]; !found {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if val, ok := conf.GetConfigAnnotation(key); ok {
|
|
|
|
|
conf.AppendPodAnnotation(key, val)
|
|
|
|
|
}
|
|
|
|
|
func (conf *ResourceConfig) GetNsAnnotations() map[string]string {
|
|
|
|
|
return conf.nsAnnotations
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (conf *ResourceConfig) GetWorkloadAnnotations() map[string]string {
|
|
|
|
|
if conf.IsPod() {
|
|
|
|
|
return conf.pod.meta.Annotations
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return conf.workload.Meta.Annotations
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AppendPodAnnotations appends the given annotations to the pod spec in conf
|
|
|
|
@ -268,25 +591,30 @@ func (conf *ResourceConfig) GetValues() *l5dcharts.Values {
|
|
|
|
|
return conf.values
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetOverriddenValues returns the final Values struct which is created
|
|
|
|
|
// by overriding annotated configuration on top of default Values
|
|
|
|
|
func (conf *ResourceConfig) GetOverriddenValues() (*l5dcharts.Values, error) {
|
|
|
|
|
// Make a copy of Values and mutate that
|
|
|
|
|
copyValues, err := conf.values.DeepCopy()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
func (conf *ResourceConfig) getAnnotationOverrides() map[string]string {
|
|
|
|
|
overrides := map[string]string{}
|
|
|
|
|
for k, v := range conf.pod.meta.Annotations {
|
|
|
|
|
overrides[k] = v
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
copyValues.Proxy.PodInboundPorts = getPodInboundPorts(conf.pod.spec)
|
|
|
|
|
conf.applyAnnotationOverrides(copyValues)
|
|
|
|
|
return copyValues, nil
|
|
|
|
|
if conf.origin != OriginCLI {
|
|
|
|
|
for k, v := range conf.pod.annotations {
|
|
|
|
|
overrides[k] = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return overrides
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetPodPatch returns the JSON patch containing the proxy and init containers specs, if any.
|
|
|
|
|
// If injectProxy is false, only the config.linkerd.io annotations are set.
|
|
|
|
|
func (conf *ResourceConfig) GetPodPatch(injectProxy bool) ([]byte, error) {
|
|
|
|
|
namedPorts := make(map[string]int32)
|
|
|
|
|
if conf.HasPodTemplate() {
|
|
|
|
|
namedPorts = util.GetNamedPorts(conf.pod.spec.Containers)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
values, err := conf.GetOverriddenValues()
|
|
|
|
|
values, err := GetOverriddenValues(conf.values, conf.getAnnotationOverrides(), namedPorts)
|
|
|
|
|
values.Proxy.PodInboundPorts = getPodInboundPorts(conf.pod.spec)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("could not generate Overridden Values: %w", err)
|
|
|
|
|
}
|
|
|
|
@ -357,20 +685,16 @@ func (conf *ResourceConfig) GetPodPatch(injectProxy bool) ([]byte, error) {
|
|
|
|
|
// value for a given key. The second is used to decide whether or not the caller
|
|
|
|
|
// should add the annotation. The caller should not add the annotation if the
|
|
|
|
|
// resource already has its own.
|
|
|
|
|
func (conf *ResourceConfig) GetConfigAnnotation(annotationKey string) (string, bool) {
|
|
|
|
|
_, ok := conf.pod.meta.Annotations[annotationKey]
|
|
|
|
|
func GetConfigOverride(annotationKey string, workloadAnn map[string]string, nsAnn map[string]string) (string, bool) {
|
|
|
|
|
_, ok := workloadAnn[annotationKey]
|
|
|
|
|
if ok {
|
|
|
|
|
log.Debugf("using pod %s %s annotation value", conf.pod.meta.Name, annotationKey)
|
|
|
|
|
log.Debugf("using workload %s annotation value", annotationKey)
|
|
|
|
|
return "", false
|
|
|
|
|
}
|
|
|
|
|
_, ok = conf.workload.Meta.Annotations[annotationKey]
|
|
|
|
|
|
|
|
|
|
annotation, ok := nsAnn[annotationKey]
|
|
|
|
|
if ok {
|
|
|
|
|
log.Debugf("using service %s %s annotation value", conf.workload.Meta.Name, annotationKey)
|
|
|
|
|
return "", false
|
|
|
|
|
}
|
|
|
|
|
annotation, ok := conf.nsAnnotations[annotationKey]
|
|
|
|
|
if ok {
|
|
|
|
|
log.Debugf("using namespace %s %s annotation value", conf.workload.Meta.Namespace, annotationKey)
|
|
|
|
|
log.Debugf("using namespace %s annotation value", annotationKey)
|
|
|
|
|
return annotation, true
|
|
|
|
|
}
|
|
|
|
|
return "", false
|
|
|
|
@ -384,7 +708,12 @@ func (conf *ResourceConfig) CreateOpaquePortsPatch() ([]byte, error) {
|
|
|
|
|
// does not need to be created.
|
|
|
|
|
return nil, nil
|
|
|
|
|
}
|
|
|
|
|
opaquePorts, ok := conf.GetConfigAnnotation(k8s.ProxyOpaquePortsAnnotation)
|
|
|
|
|
workloadAnn := conf.workload.Meta.Annotations
|
|
|
|
|
if conf.IsPod() {
|
|
|
|
|
workloadAnn = conf.pod.meta.Annotations
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
opaquePorts, ok := GetConfigOverride(k8s.ProxyOpaquePortsAnnotation, workloadAnn, conf.nsAnnotations)
|
|
|
|
|
if ok {
|
|
|
|
|
// The workload's namespace has the opaque ports annotation, so it
|
|
|
|
|
// should inherit that value. A patch is created which adds that
|
|
|
|
@ -839,314 +1168,6 @@ func (conf *ResourceConfig) injectPodAnnotations(values *podPatch) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (conf *ResourceConfig) applyAnnotationOverrides(values *l5dcharts.Values) {
|
|
|
|
|
annotations := make(map[string]string)
|
|
|
|
|
for k, v := range conf.pod.meta.Annotations {
|
|
|
|
|
annotations[k] = v
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If injecting from CLI, skip applying overrides from new annotations;
|
|
|
|
|
// overrides in this case should already be applied through flags.
|
|
|
|
|
if conf.origin != OriginCLI {
|
|
|
|
|
// Override base values inferred from current pod annotations with
|
|
|
|
|
// values from annotations that will be applied to pod after the patch.
|
|
|
|
|
for k, v := range conf.pod.annotations {
|
|
|
|
|
annotations[k] = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyInjectAnnotation]; ok {
|
|
|
|
|
if override == k8s.ProxyInjectIngress {
|
|
|
|
|
values.Proxy.IsIngress = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyImageAnnotation]; ok {
|
|
|
|
|
values.Proxy.Image.Name = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyVersionOverrideAnnotation]; ok {
|
|
|
|
|
values.Proxy.Image.Version = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyImagePullPolicyAnnotation]; ok {
|
|
|
|
|
values.Proxy.Image.PullPolicy = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyInitImageVersionAnnotation]; ok {
|
|
|
|
|
values.ProxyInit.Image.Version = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyControlPortAnnotation]; ok {
|
|
|
|
|
controlPort, err := strconv.ParseInt(override, 10, 32)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.Ports.Control = int32(controlPort)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyInboundPortAnnotation]; ok {
|
|
|
|
|
inboundPort, err := strconv.ParseInt(override, 10, 32)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.Ports.Inbound = int32(inboundPort)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyAdminPortAnnotation]; ok {
|
|
|
|
|
adminPort, err := strconv.ParseInt(override, 10, 32)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.Ports.Admin = int32(adminPort)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyOutboundPortAnnotation]; ok {
|
|
|
|
|
outboundPort, err := strconv.ParseInt(override, 10, 32)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.Ports.Outbound = int32(outboundPort)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyPodInboundPortsAnnotation]; ok {
|
|
|
|
|
values.Proxy.PodInboundPorts = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyLogLevelAnnotation]; ok {
|
|
|
|
|
values.Proxy.LogLevel = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyLogFormatAnnotation]; ok {
|
|
|
|
|
values.Proxy.LogFormat = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyRequireIdentityOnInboundPortsAnnotation]; ok {
|
|
|
|
|
values.Proxy.RequireIdentityOnInboundPorts = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyOutboundConnectTimeout]; ok {
|
|
|
|
|
duration, err := time.ParseDuration(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("unrecognized proxy-outbound-connect-timeout duration value found on pod annotation: %s", err.Error())
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.OutboundConnectTimeout = fmt.Sprintf("%dms", int(duration.Seconds()*1000))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyInboundConnectTimeout]; ok {
|
|
|
|
|
duration, err := time.ParseDuration(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("unrecognized proxy-inbound-connect-timeout duration value found on pod annotation: %s", err.Error())
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.InboundConnectTimeout = fmt.Sprintf("%dms", int(duration.Seconds()*1000))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyOutboundDiscoveryCacheUnusedTimeout]; ok {
|
|
|
|
|
duration, err := time.ParseDuration(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("unrecognized duration value used on pod annotation %s: %s", k8s.ProxyOutboundDiscoveryCacheUnusedTimeout, err.Error())
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.OutboundDiscoveryCacheUnusedTimeout = fmt.Sprintf("%ds", int(duration.Seconds()))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyInboundDiscoveryCacheUnusedTimeout]; ok {
|
|
|
|
|
duration, err := time.ParseDuration(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("unrecognized duration value used on pod annotation %s: %s", k8s.ProxyInboundDiscoveryCacheUnusedTimeout, err.Error())
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.InboundDiscoveryCacheUnusedTimeout = fmt.Sprintf("%ds", int(duration.Seconds()))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyDisableOutboundProtocolDetectTimeout]; ok {
|
|
|
|
|
value, err := strconv.ParseBool(override)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.DisableOutboundProtocolDetectTimeout = value
|
|
|
|
|
} else {
|
|
|
|
|
log.Warnf("unrecognised value used on pod annotation %s: %s", k8s.ProxyDisableOutboundProtocolDetectTimeout, err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyDisableInboundProtocolDetectTimeout]; ok {
|
|
|
|
|
value, err := strconv.ParseBool(override)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.DisableInboundProtocolDetectTimeout = value
|
|
|
|
|
} else {
|
|
|
|
|
log.Warnf("unrecognised value used on pod annotation %s: %s", k8s.ProxyDisableInboundProtocolDetectTimeout, err.Error())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyShutdownGracePeriodAnnotation]; ok {
|
|
|
|
|
duration, err := time.ParseDuration(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("unrecognized proxy-shutdown-grace-period duration value found on pod annotation: %s", err.Error())
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.ShutdownGracePeriod = fmt.Sprintf("%dms", int(duration.Seconds()*1000))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyEnableGatewayAnnotation]; ok {
|
|
|
|
|
value, err := strconv.ParseBool(override)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.IsGateway = value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyWaitBeforeExitSecondsAnnotation]; ok {
|
|
|
|
|
waitBeforeExitSeconds, err := strconv.ParseUint(override, 10, 64)
|
|
|
|
|
if nil != err {
|
|
|
|
|
log.Warnf("unrecognized value used for the %s annotation, uint64 is expected: %s",
|
|
|
|
|
k8s.ProxyWaitBeforeExitSecondsAnnotation, override)
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.WaitBeforeExitSeconds = waitBeforeExitSeconds
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyEnableNativeSidecarAnnotation]; ok {
|
|
|
|
|
value, err := strconv.ParseBool(override)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.NativeSidecar = value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyCPURequestAnnotation]; ok {
|
|
|
|
|
_, err := k8sResource.ParseQuantity(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("%s (%s)", err, k8s.ProxyCPURequestAnnotation)
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.Resources.CPU.Request = override
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyMemoryRequestAnnotation]; ok {
|
|
|
|
|
_, err := k8sResource.ParseQuantity(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("%s (%s)", err, k8s.ProxyMemoryRequestAnnotation)
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.Resources.Memory.Request = override
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyEphemeralStorageRequestAnnotation]; ok {
|
|
|
|
|
_, err := k8sResource.ParseQuantity(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("%s (%s)", err, k8s.ProxyEphemeralStorageRequestAnnotation)
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.Resources.EphemeralStorage.Request = override
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyCPULimitAnnotation]; ok {
|
|
|
|
|
q, err := k8sResource.ParseQuantity(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("%s (%s)", err, k8s.ProxyCPULimitAnnotation)
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.Resources.CPU.Limit = override
|
|
|
|
|
|
|
|
|
|
n, err := ToWholeCPUCores(q)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("%s (%s)", err, k8s.ProxyCPULimitAnnotation)
|
|
|
|
|
}
|
|
|
|
|
values.Proxy.Cores = n
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyMemoryLimitAnnotation]; ok {
|
|
|
|
|
_, err := k8sResource.ParseQuantity(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("%s (%s)", err, k8s.ProxyMemoryLimitAnnotation)
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.Resources.Memory.Limit = override
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyEphemeralStorageLimitAnnotation]; ok {
|
|
|
|
|
_, err := k8sResource.ParseQuantity(override)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Warnf("%s (%s)", err, k8s.ProxyEphemeralStorageLimitAnnotation)
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.Resources.EphemeralStorage.Limit = override
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyUIDAnnotation]; ok {
|
|
|
|
|
v, err := strconv.ParseInt(override, 10, 64)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.UID = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyEnableExternalProfilesAnnotation]; ok {
|
|
|
|
|
value, err := strconv.ParseBool(override)
|
|
|
|
|
if err == nil {
|
|
|
|
|
values.Proxy.EnableExternalProfiles = value
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyInitImageAnnotation]; ok {
|
|
|
|
|
values.ProxyInit.Image.Name = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyImagePullPolicyAnnotation]; ok {
|
|
|
|
|
values.ProxyInit.Image.PullPolicy = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyIgnoreInboundPortsAnnotation]; ok {
|
|
|
|
|
values.ProxyInit.IgnoreInboundPorts = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyIgnoreOutboundPortsAnnotation]; ok {
|
|
|
|
|
values.ProxyInit.IgnoreOutboundPorts = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyOpaquePortsAnnotation]; ok {
|
|
|
|
|
var opaquePorts strings.Builder
|
|
|
|
|
for _, pr := range util.ParseContainerOpaquePorts(override, conf.pod.spec.Containers) {
|
|
|
|
|
if opaquePorts.Len() > 0 {
|
|
|
|
|
opaquePorts.WriteRune(',')
|
|
|
|
|
}
|
|
|
|
|
opaquePorts.WriteString(pr.ToString())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
values.Proxy.OpaquePorts = opaquePorts.String()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.DebugImageAnnotation]; ok {
|
|
|
|
|
values.DebugContainer.Image.Name = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.DebugImageVersionAnnotation]; ok {
|
|
|
|
|
values.DebugContainer.Image.Version = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.DebugImagePullPolicyAnnotation]; ok {
|
|
|
|
|
values.DebugContainer.Image.PullPolicy = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyAwait]; ok {
|
|
|
|
|
if override == k8s.Enabled || override == k8s.Disabled {
|
|
|
|
|
values.Proxy.Await = override == k8s.Enabled
|
|
|
|
|
} else {
|
|
|
|
|
log.Warnf("unrecognized value used for the %s annotation, valid values are: [%s, %s]", k8s.ProxyAwait, k8s.Enabled, k8s.Disabled)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyDefaultInboundPolicyAnnotation]; ok {
|
|
|
|
|
if override != k8s.AllUnauthenticated && override != k8s.AllAuthenticated && override != k8s.ClusterUnauthenticated && override != k8s.ClusterAuthenticated && override != k8s.Deny {
|
|
|
|
|
log.Warnf("unrecognized value used for the %s annotation, valid values are: [%s, %s, %s, %s, %s]", k8s.ProxyDefaultInboundPolicyAnnotation, k8s.AllUnauthenticated, k8s.AllAuthenticated, k8s.ClusterUnauthenticated, k8s.ClusterAuthenticated, k8s.Deny)
|
|
|
|
|
} else {
|
|
|
|
|
values.Proxy.DefaultInboundPolicy = override
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxySkipSubnetsAnnotation]; ok {
|
|
|
|
|
values.ProxyInit.SkipSubnets = override
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if override, ok := annotations[k8s.ProxyAccessLogAnnotation]; ok {
|
|
|
|
|
values.Proxy.AccessLog = override
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetOverriddenConfiguration returns a map of the overridden proxy annotations
|
|
|
|
|
func (conf *ResourceConfig) GetOverriddenConfiguration() map[string]string {
|
|
|
|
|
proxyOverrideConfig := map[string]string{}
|
|
|
|
|