Skip to content
This repository has been archived by the owner on Dec 11, 2023. It is now read-only.

Improve error message when OneAgentAPM instance doesn't exist #327

Merged
merged 3 commits into from
Oct 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* Add linter to TravisCI pipeline ([#316](https://github.com/Dynatrace/dynatrace-oneagent-operator/pull/316))
* App-only init container will log an warning when the full-stack OneAgent has been injected on it ([#323](https://github.com/Dynatrace/dynatrace-oneagent-operator/pull/323))
* Experimental: support full-stack OneAgent running on non-privileged mode ([#324](https://github.com/Dynatrace/dynatrace-oneagent-operator/pull/324))
* Improve error message when OneAgentAPM is missing ([#327](https://github.com/Dynatrace/dynatrace-oneagent-operator/pull/327))

## v0.8

Expand Down
24 changes: 14 additions & 10 deletions pkg/webhook/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
dtwebhook "github.com/Dynatrace/dynatrace-oneagent-operator/pkg/webhook"
"github.com/operator-framework/operator-sdk/pkg/k8sutil"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
Expand Down Expand Up @@ -81,22 +82,25 @@ func (m *podInjector) Handle(ctx context.Context, req admission.Request) admissi
return admission.Errored(http.StatusInternalServerError, err)
}

inject := utils.GetField(ns.Annotations, dtwebhook.AnnotationInject, "true")
inject = utils.GetField(pod.Annotations, dtwebhook.AnnotationInject, inject)
if inject == "false" {
return admission.Patched("")
}

oaName := utils.GetField(ns.Labels, dtwebhook.LabelInstance, "")
if oaName == "" {
return admission.Errored(http.StatusBadRequest, fmt.Errorf("no OneAgentAPM instance set for namespace: %s", req.Namespace))
}

var oa dynatracev1alpha1.OneAgentAPM
if err := m.client.Get(ctx, client.ObjectKey{Name: oaName, Namespace: m.namespace}, &oa); err != nil {
if err := m.client.Get(ctx, client.ObjectKey{Name: oaName, Namespace: m.namespace}, &oa); k8serrors.IsNotFound(err) {
return admission.Errored(http.StatusBadRequest, fmt.Errorf(
"namespace '%s' is assigned to OneAgentAPM instance '%s' but doesn't exist", req.Namespace, oaName))
} else if err != nil {
return admission.Errored(http.StatusInternalServerError, err)
}

inject := utils.GetField(ns.Annotations, dtwebhook.AnnotationInject, "true")
inject = utils.GetField(pod.Annotations, dtwebhook.AnnotationInject, inject)
if inject == "false" {
return admission.Patched("")
}

if pod.Annotations == nil {
pod.Annotations = map[string]string{}
}
Expand All @@ -109,12 +113,12 @@ func (m *podInjector) Handle(ctx context.Context, req admission.Request) admissi
flavor := url.QueryEscape(utils.GetField(pod.Annotations, dtwebhook.AnnotationFlavor, "default"))
technologies := url.QueryEscape(utils.GetField(pod.Annotations, dtwebhook.AnnotationTechnologies, "all"))
installPath := utils.GetField(pod.Annotations, dtwebhook.AnnotationInstallPath, dtwebhook.DefaultInstallPath)
installerUrl := utils.GetField(pod.Annotations, dtwebhook.AnnotationInstallerUrl, "")
installerURL := utils.GetField(pod.Annotations, dtwebhook.AnnotationInstallerUrl, "")
imageAnnotation := utils.GetField(pod.Annotations, dtwebhook.AnnotationImage, "")
failurePolicy := utils.GetField(pod.Annotations, dtwebhook.AnnotationFailurePolicy, "silent")
image := m.image

if installerUrl == "" && oa.Status.UseImmutableImage {
if installerURL == "" && oa.Status.UseImmutableImage {
if oa.Spec.Image == "" && imageAnnotation == "" {
image, err = utils.BuildOneAgentAPMImage(oa.Spec.APIURL, flavor, technologies, oa.Spec.AgentVersion)
if err != nil {
Expand Down Expand Up @@ -180,7 +184,7 @@ func (m *podInjector) Handle(ctx context.Context, req admission.Request) admissi
{Name: "FLAVOR", Value: flavor},
{Name: "TECHNOLOGIES", Value: technologies},
{Name: "INSTALLPATH", Value: installPath},
{Name: "INSTALLER_URL", Value: installerUrl},
{Name: "INSTALLER_URL", Value: installerURL},
{Name: "FAILURE_POLICY", Value: failurePolicy},
{Name: "CONTAINERS_COUNT", Value: strconv.Itoa(len(pod.Spec.Containers))},
{Name: "K8S_PODNAME", ValueFrom: fieldEnvVar("metadata.name")},
Expand Down
33 changes: 33 additions & 0 deletions pkg/webhook/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,39 @@ func init() {

const installOneAgentContainerName = "install-oneagent"

func TestInjectionWithMissingOneAgentAPM(t *testing.T) {
decoder, err := admission.NewDecoder(scheme.Scheme)
require.NoError(t, err)

inj := &podInjector{
client: fake.NewFakeClientWithScheme(scheme.Scheme,
&corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "test-namespace",
Labels: map[string]string{"oneagent.dynatrace.com/instance": "oneagent"},
},
}),
decoder: decoder,
image: "operator-image",
namespace: "dynatrace",
}

basePod := corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "test-pod-123456", Namespace: "test-namespace"}}
basePodBytes, err := json.Marshal(&basePod)
require.NoError(t, err)

req := admission.Request{
AdmissionRequest: admissionv1beta1.AdmissionRequest{
Object: runtime.RawExtension{Raw: basePodBytes},
Namespace: "test-namespace",
},
}
resp := inj.Handle(context.TODO(), req)
require.NoError(t, resp.Complete(req))
require.False(t, resp.Allowed)
require.Equal(t, resp.Result.Message, "namespace 'test-namespace' is assigned to OneAgentAPM instance 'oneagent' but doesn't exist")
}

func TestPodInjection(t *testing.T) {
decoder, err := admission.NewDecoder(scheme.Scheme)
require.NoError(t, err)
Expand Down