Skip to content

Commit

Permalink
Fix dynatrace-operator functionality (#25)
Browse files Browse the repository at this point in the history
* Fix dynatrace-operator functionality
  • Loading branch information
DTMad committed Nov 17, 2020
1 parent a14e7e1 commit c0320fb
Show file tree
Hide file tree
Showing 13 changed files with 91 additions and 137 deletions.
7 changes: 4 additions & 3 deletions deploy/manifest/role-operator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ rules:
- apiGroups:
- dynatrace.com
resources:
- activegates
- dynakubes
verbs:
- get
- list
Expand All @@ -20,8 +20,8 @@ rules:
- apiGroups:
- dynatrace.com
resources:
- activegates/finalizers
- activegates/status
- dynakubes/finalizers
- dynakubes/status
verbs:
- update

Expand Down Expand Up @@ -96,6 +96,7 @@ rules:
- services
verbs:
- create
- get

- apiGroups:
- policy
Expand Down
7 changes: 5 additions & 2 deletions pkg/controller/activegate/activegate_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func Add(mgr manager.Manager) error {
func newReconciler(mgr manager.Manager) reconcile.Reconciler {
return &ReconcileActiveGate{
client: mgr.GetClient(),
apiReader: mgr.GetAPIReader(),
scheme: mgr.GetScheme(),
dtcBuildFunc: builder.BuildDynatraceClient,
updateService: &activeGateUpdateService{},
Expand Down Expand Up @@ -77,6 +78,7 @@ type ReconcileActiveGate struct {
// This client, initialized using mgr.Client() above, is a split client
// that reads objects from the cache and writes to the apiserver
client client.Client
apiReader client.Reader
scheme *runtime.Scheme
dtcBuildFunc DynatraceClientFunc
updateService updateService
Expand Down Expand Up @@ -109,6 +111,7 @@ func (r *ReconcileActiveGate) Reconcile(request reconcile.Request) (reconcile.Re
}

if !instance.Spec.KubernetesMonitoringSpec.Enabled {
reqLogger.Info("Kubernetes monitoring disabled")
return builder.ReconcileAfterFiveMinutes(), nil
}

Expand Down Expand Up @@ -142,7 +145,7 @@ func (r *ReconcileActiveGate) Reconcile(request reconcile.Request) (reconcile.Re
}
}

desiredStatefulSet, err := r.createDesiredStatefulSet(instance, dtc)
desiredStatefulSet, err := r.createDesiredStatefulSet(instance)
if err != nil {
reqLogger.Error(err, "error when creating desired stateful set")
return reconcile.Result{}, err
Expand Down Expand Up @@ -172,7 +175,7 @@ func (r *ReconcileActiveGate) Reconcile(request reconcile.Request) (reconcile.Re
if errors.As(err, &statusError) {
// Since this happens early during deployment, pods might have been modified
// In this case, retry silently
return builder.ReconcileAfter(5 * time.Second), nil
return builder.ReconcileAfterFiveMinutes(), nil
}
// Otherwise, retry loudly
return builder.ReconcileAfterFiveMinutes(), err
Expand Down
11 changes: 7 additions & 4 deletions pkg/controller/activegate/activegate_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/Dynatrace/dynatrace-operator/pkg/controller/builder"
_const "github.com/Dynatrace/dynatrace-operator/pkg/controller/const"
"github.com/Dynatrace/dynatrace-operator/pkg/controller/factory"
"github.com/Dynatrace/dynatrace-operator/pkg/dtclient"
"github.com/operator-framework/operator-sdk/pkg/k8sutil"
"github.com/stretchr/testify/assert"
appsv1 "k8s.io/api/apps/v1"
Expand Down Expand Up @@ -84,7 +83,7 @@ func TestReconcile(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, result, builder.ReconcileImmediately())

sts, err := r.newStatefulSetForCR(instance, &dtclient.TenantInfo{}, factory.KubeSystemUID)
sts, err := r.newStatefulSetForCR(instance, factory.KubeSystemUID)
assert.NoError(t, err)
assert.NotNil(t, sts)

Expand Down Expand Up @@ -186,8 +185,10 @@ func TestReconcile(t *testing.T) {
assert.Equal(t, result, builder.ReconcileAfterFiveMinutes())
})
t.Run("Reconcile pod has uid env", func(t *testing.T) {
fakeClient := factory.CreateFakeClient()
r := &ReconcileActiveGate{
client: factory.CreateFakeClient(),
client: fakeClient,
apiReader: fakeClient,
dtcBuildFunc: createFakeDTClient,
scheme: scheme.Scheme,
updateService: &mockIsLatestUpdateService{},
Expand Down Expand Up @@ -234,8 +235,10 @@ func TestReconcile(t *testing.T) {
}
})
t.Run("Reconcile no kube-system namespace", func(t *testing.T) {
fakeClient := factory.CreateFakeClient()
r := &ReconcileActiveGate{
client: factory.CreateFakeClient(),
client: fakeClient,
apiReader: fakeClient,
dtcBuildFunc: createFakeDTClient,
scheme: scheme.Scheme,
updateService: &mockIsLatestUpdateService{},
Expand Down
5 changes: 2 additions & 3 deletions pkg/controller/activegate/activegate_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
dynatracev1alpha1 "github.com/Dynatrace/dynatrace-operator/pkg/apis/dynatrace/v1alpha1"
"github.com/Dynatrace/dynatrace-operator/pkg/controller/builder"
_const "github.com/Dynatrace/dynatrace-operator/pkg/controller/const"
"github.com/Dynatrace/dynatrace-operator/pkg/dtclient"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -61,9 +60,9 @@ func newConfigSecret(secretName string, data string) *corev1.Secret {
}
}

func (r *ReconcileActiveGate) newStatefulSetForCR(instance *dynatracev1alpha1.DynaKube, tenantInfo *dtclient.TenantInfo, kubeSystemUID types.UID) (*appsv1.StatefulSet, error) {
func (r *ReconcileActiveGate) newStatefulSetForCR(instance *dynatracev1alpha1.DynaKube, kubeSystemUID types.UID) (*appsv1.StatefulSet, error) {

podSpec, err := builder.BuildActiveGatePodSpecs(instance, tenantInfo, kubeSystemUID)
podSpec, err := builder.BuildActiveGatePodSpecs(instance, kubeSystemUID)
if err != nil {
return nil, err
}
Expand Down
3 changes: 1 addition & 2 deletions pkg/controller/activegate/activegate_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (

"github.com/Dynatrace/dynatrace-operator/pkg/apis/dynatrace/v1alpha1"
_const "github.com/Dynatrace/dynatrace-operator/pkg/controller/const"
"github.com/Dynatrace/dynatrace-operator/pkg/dtclient"
"github.com/stretchr/testify/assert"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
Expand All @@ -21,7 +20,7 @@ func TestCreateStatefulSet(t *testing.T) {
assert.NotNil(t, r)
assert.NoError(t, err)

result, err := r.newStatefulSetForCR(instance, &dtclient.TenantInfo{}, "")
result, err := r.newStatefulSetForCR(instance, "")
assert.NoError(t, err)
assert.NotNil(t, result)
}
Expand Down
1 change: 1 addition & 0 deletions pkg/controller/activegate/activegate_update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ func setupReconciler(t *testing.T, updateService updateService) (*ReconcileActiv
fakeClient := factory.CreateFakeClient()
r := &ReconcileActiveGate{
client: fakeClient,
apiReader: fakeClient,
dtcBuildFunc: createFakeDTClient,
scheme: scheme.Scheme,
updateService: updateService,
Expand Down
20 changes: 19 additions & 1 deletion pkg/controller/activegate/pull_secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,37 @@ import (
"github.com/Dynatrace/dynatrace-operator/pkg/dtclient"
"github.com/go-logr/logr"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
)

func (r *ReconcileActiveGate) reconcilePullSecret(instance *dynatracev1alpha1.DynaKube, log logr.Logger, dtc dtclient.Client) error {
var tkns corev1.Secret

if err := r.client.Get(context.TODO(), client.ObjectKey{Name: parser.GetTokensName(instance), Namespace: instance.GetNamespace()}, &tkns); err != nil {
return fmt.Errorf("failed to query tokens: %w", err)
}
pullSecretData, err := builder.GeneratePullSecretData(instance, dtc, &tkns)
if err != nil {
return fmt.Errorf("failed to generate pull secret data: %w", err)
}
err = factory.CreateOrUpdateSecret(r.client, instance.GetName()+"-pull-secret", instance.GetNamespace(), pullSecretData, corev1.SecretTypeDockerConfigJson, log)

var secretManager = &factory.SecretManager{
Client: r.client,
Scheme: r.scheme,
Logger: log,
Secret: &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: instance.GetName() + "-pull-secret",
Namespace: instance.Namespace,
},
Data: pullSecretData,
Type: corev1.DockerConfigJsonKey,
},
Owner: instance,
}

err = factory.CreateOrUpdateSecret(secretManager)
if err != nil {
return fmt.Errorf("failed to create or update secret: %w", err)
}
Expand Down
12 changes: 3 additions & 9 deletions pkg/controller/activegate/stateful_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/Dynatrace/dynatrace-operator/pkg/apis/dynatrace/v1alpha1"
"github.com/Dynatrace/dynatrace-operator/pkg/controller/builder"
"github.com/Dynatrace/dynatrace-operator/pkg/controller/dao"
"github.com/Dynatrace/dynatrace-operator/pkg/dtclient"
"github.com/go-logr/logr"
appsv1 "k8s.io/api/apps/v1"
"k8s.io/apimachinery/pkg/api/errors"
Expand All @@ -16,18 +15,13 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)

func (r *ReconcileActiveGate) createDesiredStatefulSet(instance *v1alpha1.DynaKube, dtc dtclient.Client) (*appsv1.StatefulSet, error) {
tenantInfo, err := dtc.GetTenantInfo()
func (r *ReconcileActiveGate) createDesiredStatefulSet(instance *v1alpha1.DynaKube) (*appsv1.StatefulSet, error) {
uid, err := dao.FindKubeSystemUID(r.apiReader)
if err != nil {
return nil, err
}

uid, err := dao.FindKubeSystemUID(r.client)
if err != nil {
return nil, err
}

desiredStatefulSet, err := r.newStatefulSetForCR(instance, tenantInfo, uid)
desiredStatefulSet, err := r.newStatefulSetForCR(instance, uid)
if err != nil {
return nil, err
}
Expand Down
25 changes: 2 additions & 23 deletions pkg/controller/activegate/stateful_set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ package activegate

import (
"context"
"fmt"
"testing"

_const "github.com/Dynatrace/dynatrace-operator/pkg/controller/const"
"github.com/Dynatrace/dynatrace-operator/pkg/dtclient"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand All @@ -17,41 +15,22 @@ func TestCreateDesiredStatefulSet(t *testing.T) {
r, instance, err := setupReconciler(t, &mockIsLatestUpdateService{})
assert.NoError(t, err)

dtc, err := createFakeDTClient(nil, nil, nil)
assert.NoError(t, err)

desiredStatefulSet, err := r.createDesiredStatefulSet(instance, dtc)
desiredStatefulSet, err := r.createDesiredStatefulSet(instance)
assert.NoError(t, err)
assert.NotNil(t, desiredStatefulSet)
})
t.Run("CreateDesiredStatefulSet error getting tenant info", func(t *testing.T) {
r, instance, err := setupReconciler(t, &mockIsLatestUpdateService{})
assert.NoError(t, err)

dtc := &dtclient.MockDynatraceClient{}
dtc.
On("GetTenantInfo").
Return(&dtclient.TenantInfo{}, fmt.Errorf("could not retrieve tenant info"))

desiredStatefulSet, err := r.createDesiredStatefulSet(instance, dtc)
assert.EqualError(t, err, "could not retrieve tenant info")
assert.Nil(t, desiredStatefulSet)
})
t.Run("CreateDesiredStatefulSet no kube-system", func(t *testing.T) {
r, instance, err := setupReconciler(t, &mockIsLatestUpdateService{})
assert.NoError(t, err)

dtc, err := createFakeDTClient(nil, nil, nil)
assert.NoError(t, err)

kubeSystemNamespace := &corev1.Namespace{}
err = r.client.Get(context.TODO(), client.ObjectKey{Name: _const.KubeSystemNamespace}, kubeSystemNamespace)
assert.NoError(t, err)

err = r.client.Delete(context.TODO(), kubeSystemNamespace)
assert.NoError(t, err)

desiredStatefulSet, err := r.createDesiredStatefulSet(instance, dtc)
desiredStatefulSet, err := r.createDesiredStatefulSet(instance)
assert.EqualError(t, err, "namespaces \"kube-system\" not found")
assert.Nil(t, desiredStatefulSet)
})
Expand Down
39 changes: 6 additions & 33 deletions pkg/controller/builder/pod_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,15 @@ import (

"github.com/Dynatrace/dynatrace-operator/pkg/apis/dynatrace/v1alpha1"
_const "github.com/Dynatrace/dynatrace-operator/pkg/controller/const"
"github.com/Dynatrace/dynatrace-operator/pkg/dtclient"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
)

func BuildActiveGatePodSpecs(instance *v1alpha1.DynaKube, tenantInfo *dtclient.TenantInfo, kubeSystemUID types.UID) (corev1.PodSpec, error) {
func BuildActiveGatePodSpecs(instance *v1alpha1.DynaKube, kubeSystemUID types.UID) (corev1.PodSpec, error) {
var volumeMounts []corev1.VolumeMount
var volumes []corev1.Volume

sa := MonitoringServiceAccount
activeGateSpec := &instance.Spec.KubernetesMonitoringSpec
additionalArgs := activeGateSpec.Args
Expand All @@ -25,15 +23,11 @@ func BuildActiveGatePodSpecs(instance *v1alpha1.DynaKube, tenantInfo *dtclient.T
if activeGateSpec.ServiceAccountName != "" {
sa = activeGateSpec.ServiceAccountName
}
if tenantInfo == nil {
tenantInfo = &dtclient.TenantInfo{
ID: "",
Token: "",
Endpoints: []string{},
}
if activeGateSpec.Image != "" {
image = activeGateSpec.Image
}

envVars := buildEnvVars(instance, tenantInfo, kubeSystemUID)
envVars := buildEnvVars(instance, kubeSystemUID)

checkMinimumResources(activeGateSpec)

Expand Down Expand Up @@ -259,33 +253,18 @@ func buildReadinessProbe() *corev1.Probe {

func buildArgs(additionalArgs []string) []string {
return append([]string{
DtTenantArg,
DtTokenArg,
DtServerArg,
DtCapabilitiesArg,
}, additionalArgs...)
}

func buildEnvVars(instance *v1alpha1.DynaKube, tenantInfo *dtclient.TenantInfo, kubeSystemUID types.UID) []corev1.EnvVar {
func buildEnvVars(instance *v1alpha1.DynaKube, kubeSystemUID types.UID) []corev1.EnvVar {
var capabilities []string

if instance.Spec.KubernetesMonitoringSpec.Enabled {
capabilities = append(capabilities, "kubernetes_monitoring")
}

return append([]corev1.EnvVar{
{
Name: DtTenant,
Value: tenantInfo.ID,
},
{
Name: DtToken,
Value: tenantInfo.Token,
},
{
Name: DtServer,
Value: tenantInfo.CommunicationEndpoint,
},
{
Name: DtCapabilities,
Value: strings.Join(capabilities, Comma),
Expand Down Expand Up @@ -402,17 +381,11 @@ const (
ARM64 = "arm64"
LINUX = "linux"

DtTenant = "DT_TENANT"
DtServer = "DT_SERVER"
DtToken = "DT_TOKEN"
DtCapabilities = "DT_CAPABILITIES"
DtIdSeedNamespace = "DT_ID_SEED_NAMESPACE"
DtIdSeedClusterId = "DT_ID_SEED_K8S_CLUSTER_ID"

DtTenantArg = "--tenant=$(DT_TENANT)"
DtTokenArg = "--token=$(DT_TOKEN)"
DtServerArg = "--server=$(DT_SERVER)"
DtCapabilitiesArg = "--enable=$(DT_CAPABILITIES)"
DtCapabilitiesArg = "--enable=kubernetes_monitoring"

Comma = ","

Expand Down
Loading

0 comments on commit c0320fb

Please sign in to comment.