mirror of https://github.com/linkerd/linkerd2.git
inject: Refactor report-checking from inject logic (#2379)
The inject logic combines the modification of a pod spec and the creation of a "report" detailing problems with the pod spec. This change extracts the report-creation-and-checking logic from the injection logic to make the contracts of each of these functions clearer. No functional changes are intended.
This commit is contained in:
parent
bc735ebdc2
commit
9e67bcb1bc
|
@ -8,7 +8,6 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/linkerd/linkerd2/pkg/healthcheck"
|
||||
"github.com/linkerd/linkerd2/pkg/k8s"
|
||||
"github.com/spf13/cobra"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
|
@ -115,15 +114,8 @@ func uninjectAndInject(inputs []io.Reader, errWriter, outWriter io.Writer, optio
|
|||
return runInjectCmd([]io.Reader{&out}, errWriter, outWriter, options)
|
||||
}
|
||||
|
||||
/* Given a ObjectMeta, update ObjectMeta in place with the new labels and
|
||||
* annotations.
|
||||
*/
|
||||
func injectObjectMeta(t *metaV1.ObjectMeta, k8sLabels map[string]string, options *injectOptions, report *injectReport) bool {
|
||||
report.injectDisabled = injectDisabled(t)
|
||||
if report.injectDisabled {
|
||||
return false
|
||||
}
|
||||
|
||||
// injectObjectMeta adds linkerd labels & annotations to the provided ObjectMeta.
|
||||
func injectObjectMeta(t *metaV1.ObjectMeta, k8sLabels map[string]string, options *injectOptions) {
|
||||
if t.Annotations == nil {
|
||||
t.Annotations = make(map[string]string)
|
||||
}
|
||||
|
@ -137,27 +129,10 @@ func injectObjectMeta(t *metaV1.ObjectMeta, k8sLabels map[string]string, options
|
|||
for k, v := range k8sLabels {
|
||||
t.Labels[k] = v
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/* Given a PodSpec, update the PodSpec in place with the sidecar
|
||||
* and init-container injected. If the pod is unsuitable for having them
|
||||
* injected, return false.
|
||||
*/
|
||||
func injectPodSpec(t *v1.PodSpec, identity k8s.TLSIdentity, controlPlaneDNSNameOverride string, options *injectOptions, report *injectReport) bool {
|
||||
report.hostNetwork = t.HostNetwork
|
||||
report.sidecar = healthcheck.HasExistingSidecars(t)
|
||||
report.udp = checkUDPPorts(t)
|
||||
|
||||
// Skip injection if:
|
||||
// 1) Pods with `hostNetwork: true` share a network namespace with the host.
|
||||
// The init-container would destroy the iptables configuration on the host.
|
||||
// OR
|
||||
// 2) Known 3rd party sidecars already present.
|
||||
if report.hostNetwork || report.sidecar {
|
||||
return false
|
||||
}
|
||||
// injectPodSpec adds linkerd sidecars to the provided PodSpec.
|
||||
func injectPodSpec(t *v1.PodSpec, identity k8s.TLSIdentity, controlPlaneDNSNameOverride string, options *injectOptions) {
|
||||
|
||||
f := false
|
||||
inboundSkipPorts := append(options.ignoreInboundPorts, options.proxyControlPort, options.proxyMetricsPort)
|
||||
|
@ -358,8 +333,6 @@ func injectPodSpec(t *v1.PodSpec, identity k8s.TLSIdentity, controlPlaneDNSNameO
|
|||
}
|
||||
t.InitContainers = append(t.InitContainers, initContainer)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (rt resourceTransformerInject) transform(bytes []byte, options *injectOptions) ([]byte, []injectReport, error) {
|
||||
|
@ -394,8 +367,11 @@ func (rt resourceTransformerInject) transform(bytes []byte, options *injectOptio
|
|||
ControllerNamespace: controlPlaneNamespace,
|
||||
}
|
||||
|
||||
if injectPodSpec(conf.podSpec, identity, conf.dnsNameOverride, options, &report) &&
|
||||
injectObjectMeta(conf.objectMeta, conf.k8sLabels, options, &report) {
|
||||
report.update(conf.objectMeta, conf.podSpec)
|
||||
if report.shouldInject() {
|
||||
injectObjectMeta(conf.objectMeta, conf.k8sLabels, options)
|
||||
injectPodSpec(conf.podSpec, identity, conf.dnsNameOverride, options)
|
||||
|
||||
var err error
|
||||
output, err = yaml.Marshal(conf.obj)
|
||||
if err != nil {
|
||||
|
@ -508,19 +484,3 @@ func (resourceTransformerInject) generateReport(injectReports []injectReport, ou
|
|||
// Trailing newline to separate from kubectl output if piping
|
||||
output.Write([]byte("\n"))
|
||||
}
|
||||
|
||||
func checkUDPPorts(t *v1.PodSpec) bool {
|
||||
// Check for ports with `protocol: UDP`, which will not be routed by Linkerd
|
||||
for _, container := range t.Containers {
|
||||
for _, port := range container.Ports {
|
||||
if port.Protocol == v1.ProtocolUDP {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func injectDisabled(t *metaV1.ObjectMeta) bool {
|
||||
return t.GetAnnotations()[k8s.ProxyInjectAnnotation] == k8s.ProxyInjectDisabled
|
||||
}
|
||||
|
|
|
@ -8,10 +8,11 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/linkerd/linkerd2/pkg/healthcheck"
|
||||
"github.com/linkerd/linkerd2/pkg/k8s"
|
||||
appsV1 "k8s.io/api/apps/v1"
|
||||
batchV1 "k8s.io/api/batch/v1"
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/api/extensions/v1beta1"
|
||||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
@ -44,8 +45,39 @@ type resourceConfig struct {
|
|||
k8sLabels map[string]string
|
||||
}
|
||||
|
||||
func (i injectReport) resName() string {
|
||||
return fmt.Sprintf("%s/%s", i.kind, i.name)
|
||||
func (r injectReport) resName() string {
|
||||
return fmt.Sprintf("%s/%s", r.kind, r.name)
|
||||
}
|
||||
|
||||
// update updates the report for the provided resources.
|
||||
func (r *injectReport) update(m *metaV1.ObjectMeta, p *v1.PodSpec) {
|
||||
r.injectDisabled = m.GetAnnotations()[k8s.ProxyInjectAnnotation] == k8s.ProxyInjectDisabled
|
||||
r.hostNetwork = p.HostNetwork
|
||||
r.sidecar = healthcheck.HasExistingSidecars(p)
|
||||
r.udp = checkUDPPorts(p)
|
||||
}
|
||||
|
||||
func checkUDPPorts(t *v1.PodSpec) bool {
|
||||
// Check for ports with `protocol: UDP`, which will not be routed by Linkerd
|
||||
for _, container := range t.Containers {
|
||||
for _, port := range container.Ports {
|
||||
if port.Protocol == v1.ProtocolUDP {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// shouldInject returns false if the resource should not be injected.
|
||||
//
|
||||
// Injection is skipped in the following situations
|
||||
// - Injection is disabled by annotation
|
||||
// - Pods with `hostNetwork: true` share a network namespace with the host.
|
||||
// The init-container would destroy the iptables configuration on the host.
|
||||
// - Known 3rd party sidecars already present.
|
||||
func (r *injectReport) shouldInject() bool {
|
||||
return !r.injectDisabled && !r.hostNetwork && !r.sidecar
|
||||
}
|
||||
|
||||
// Returns the integer representation of os.Exit code; 0 on success and 1 on failure.
|
||||
|
|
Loading…
Reference in New Issue