Skip to content

Commit

Permalink
EdgeConnect pod spec enhancements for Kubernetes Automation (ServiceA…
Browse files Browse the repository at this point in the history
…ccountName, HostAlias) (#3059)

Co-authored-by: Andrii Soldatenko <[email protected]>
  • Loading branch information
aorcholski and andriisoldatenko authored May 2, 2024
1 parent 9d2d15f commit 2885871
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ rules:
- update
- delete
- list
- apiGroups:
- ""
resources:
- services
resourceNames:
- kubernetes
verbs:
- get
- apiGroups:
- ""
resources:
Expand Down
42 changes: 42 additions & 0 deletions pkg/controllers/edgeconnect/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/Dynatrace/dynatrace-operator/pkg/util/timeprovider"
"github.com/pkg/errors"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand All @@ -37,6 +38,10 @@ const (
defaultUpdateInterval = 30 * time.Minute

finalizerName = "server"

defaultNamespaceName = "default"
kubernetesServiceName = "kubernetes"
kubeSystemNamespaceName = "kube-system"
)

type oauthCredentialsType struct {
Expand Down Expand Up @@ -319,6 +324,11 @@ func (controller *Controller) reconcileEdgeConnectRegular(ctx context.Context, e

_log := log.WithValues("namespace", edgeConnect.Namespace, "name", edgeConnect.Name, "deploymentName", desiredDeployment.Name)

err := controller.hostAlias(ctx, desiredDeployment, edgeConnect.Name, edgeConnect.Namespace)
if err != nil {
return err
}

if err := controllerutil.SetControllerReference(edgeConnect, desiredDeployment, controller.scheme); err != nil {
return errors.WithStack(err)
}
Expand Down Expand Up @@ -636,6 +646,11 @@ func (controller *Controller) createOrUpdateEdgeConnectDeployment(ctx context.Co

desiredDeployment := deployment.New(edgeConnect)

err = controller.hostAlias(ctx, desiredDeployment, edgeConnect.Name, edgeConnect.Namespace)
if err != nil {
return err
}

desiredDeployment.Spec.Template.Annotations = map[string]string{consts.EdgeConnectAnnotationSecretHash: secretHash}
_log = _log.WithValues("deploymentName", desiredDeployment.Name)

Expand Down Expand Up @@ -695,3 +710,30 @@ func (controller *Controller) createOrUpdateEdgeConnectConfigSecret(ctx context.

return hasher.GenerateHash(secretConfig.Data)
}

func (controller *Controller) hostAlias(ctx context.Context, deployment *appsv1.Deployment, ecName string, ecNamespace string) error {
var kubernetesService corev1.Service

err := controller.apiReader.Get(ctx, client.ObjectKey{Namespace: defaultNamespaceName, Name: kubernetesServiceName}, &kubernetesService)
if err != nil {
return errors.WithStack(err)
}

var kubeSystemNamespace corev1.Namespace

err = controller.apiReader.Get(ctx, client.ObjectKey{Name: kubeSystemNamespaceName}, &kubeSystemNamespace)
if err != nil {
return errors.WithStack(err)
}

deployment.Spec.Template.Spec.HostAliases = []corev1.HostAlias{
{
IP: kubernetesService.Spec.ClusterIP,
Hostnames: []string{
ecName + "." + ecNamespace + "." + string(kubeSystemNamespace.UID),
},
},
}

return nil
}
59 changes: 55 additions & 4 deletions pkg/controllers/edgeconnect/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ const (
testCreatedId = "id"
testRecreatedInvalidId = "id-somehow-different"
testCAConfigMapName = "test-ca-name"

testClusterIP = "1.2.3.4"
testUID = "1-2-3-4"
)

var (
Expand All @@ -64,7 +67,11 @@ func TestReconcile(t *testing.T) {
},
},
}
controller := createFakeClientAndReconciler(t, instance, createClientSecret(testOauthClientSecret, instance.Namespace))
controller := createFakeClientAndReconciler(t, instance,
createClientSecret(testOauthClientSecret, instance.Namespace),
createKubernetesService(),
createKubeSystemNamespace(),
)

result, err := controller.Reconcile(context.TODO(), reconcile.Request{
NamespacedName: types.NamespacedName{Namespace: testNamespace, Name: testName},
Expand Down Expand Up @@ -98,7 +105,11 @@ func TestReconcile(t *testing.T) {
},
}

controller := createFakeClientAndReconciler(t, instance, createClientSecret(testOauthClientSecret, instance.Namespace))
controller := createFakeClientAndReconciler(t, instance,
createClientSecret(testOauthClientSecret, instance.Namespace),
createKubernetesService(),
createKubeSystemNamespace(),
)
controller.timeProvider.Freeze()

result, err := controller.Reconcile(context.TODO(), reconcile.Request{
Expand Down Expand Up @@ -129,7 +140,11 @@ func TestReconcile(t *testing.T) {
},
},
}
controller := createFakeClientAndReconciler(t, instance, createClientSecret(testOauthClientSecret, instance.Namespace))
controller := createFakeClientAndReconciler(t, instance,
createClientSecret(testOauthClientSecret, instance.Namespace),
createKubernetesService(),
createKubeSystemNamespace(),
)

result, err := controller.Reconcile(context.TODO(), reconcile.Request{
NamespacedName: types.NamespacedName{Namespace: testNamespace, Name: testName},
Expand Down Expand Up @@ -177,7 +192,7 @@ func TestReconcile(t *testing.T) {
customCA := newConfigMap(testCAConfigMapName, instance.Namespace, data)
clientSecret := createClientSecret(testOauthClientSecret, instance.Namespace)

controller := createFakeClientAndReconciler(t, instance, clientSecret, customCA)
controller := createFakeClientAndReconciler(t, instance, clientSecret, customCA, createKubernetesService(), createKubeSystemNamespace())

_, err := controller.Reconcile(context.TODO(), reconcile.Request{
NamespacedName: types.NamespacedName{Namespace: testNamespace, Name: testName},
Expand All @@ -198,6 +213,8 @@ func TestReconcileProvisionerCreate(t *testing.T) {
instance,
mockNewEdgeConnectClientCreate(edgeConnectClient),
createOauthSecret(instance.Spec.OAuth.ClientSecret, instance.Namespace),
createKubernetesService(),
createKubeSystemNamespace(),
)

result, err := controller.Reconcile(context.Background(), reconcile.Request{
Expand Down Expand Up @@ -238,6 +255,8 @@ func TestReconcileProvisionerCreate(t *testing.T) {
)
require.NoError(t, err)
assert.Equal(t, "edge-connect", edgeConnectDeployment.Spec.Template.Spec.Containers[0].Name)
assert.Equal(t, testClusterIP, edgeConnectDeployment.Spec.Template.Spec.HostAliases[0].IP)
assert.Equal(t, instance.Name+"."+instance.Namespace+"."+testUID, edgeConnectDeployment.Spec.Template.Spec.HostAliases[0].Hostnames[0])

edgeConnectClient.AssertCalled(t, "GetEdgeConnects", testName)
edgeConnectClient.AssertCalled(t, "CreateEdgeConnect", testName, testHostPatterns, "")
Expand All @@ -255,6 +274,8 @@ func TestReconcileProvisionerRecreate(t *testing.T) {
instance,
mockNewEdgeConnectClientRecreate(edgeConnectClient, testCreatedId),
createOauthSecret(instance.Spec.OAuth.ClientSecret, instance.Namespace),
createKubernetesService(),
createKubeSystemNamespace(),
)

result, err := controller.Reconcile(context.Background(), reconcile.Request{
Expand Down Expand Up @@ -295,6 +316,8 @@ func TestReconcileProvisionerRecreate(t *testing.T) {
)
require.NoError(t, err)
assert.Equal(t, "edge-connect", edgeConnectDeployment.Spec.Template.Spec.Containers[0].Name)
assert.Equal(t, testClusterIP, edgeConnectDeployment.Spec.Template.Spec.HostAliases[0].IP)
assert.Equal(t, instance.Name+"."+instance.Namespace+"."+testUID, edgeConnectDeployment.Spec.Template.Spec.HostAliases[0].Hostnames[0])

edgeConnectClient.AssertCalled(t, "GetEdgeConnects", testName)
edgeConnectClient.AssertCalled(t, "DeleteEdgeConnect", testCreatedId)
Expand All @@ -312,6 +335,8 @@ func TestReconcileProvisionerRecreate(t *testing.T) {
mockNewEdgeConnectClientRecreate(edgeConnectClient, testRecreatedInvalidId),
createOauthSecret(instance.Spec.OAuth.ClientSecret, instance.Namespace),
createClientSecret(instance.ClientSecretName(), instance.Namespace),
createKubernetesService(),
createKubeSystemNamespace(),
)

result, err := controller.Reconcile(context.Background(), reconcile.Request{
Expand Down Expand Up @@ -352,6 +377,8 @@ func TestReconcileProvisionerRecreate(t *testing.T) {
)
require.NoError(t, err)
assert.Equal(t, "edge-connect", edgeConnectDeployment.Spec.Template.Spec.Containers[0].Name)
assert.Equal(t, testClusterIP, edgeConnectDeployment.Spec.Template.Spec.HostAliases[0].IP)
assert.Equal(t, instance.Name+"."+instance.Namespace+"."+testUID, edgeConnectDeployment.Spec.Template.Spec.HostAliases[0].Hostnames[0])

edgeConnectClient.AssertCalled(t, "GetEdgeConnects", testName)
edgeConnectClient.AssertCalled(t, "DeleteEdgeConnect", testRecreatedInvalidId)
Expand Down Expand Up @@ -453,6 +480,8 @@ func TestReconcileProvisionerUpdate(t *testing.T) {
mockNewEdgeConnectClientUpdate(edgeConnectClient),
createOauthSecret(instance.Spec.OAuth.ClientSecret, instance.Namespace),
createClientSecret(instance.ClientSecretName(), instance.Namespace),
createKubernetesService(),
createKubeSystemNamespace(),
)

result, err := controller.Reconcile(context.Background(), reconcile.Request{
Expand Down Expand Up @@ -725,3 +754,25 @@ func createEdgeConnectProvisionerCR(finalizers []string, deletionTimestamp *meta
},
}
}

func createKubernetesService() *corev1.Service {
return &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: kubernetesServiceName,
Namespace: defaultNamespaceName,
},
Spec: corev1.ServiceSpec{
ClusterIP: testClusterIP,
},
}
}

func createKubeSystemNamespace() *corev1.Namespace {
return &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: kubeSystemNamespaceName,
Namespace: "",
UID: testUID,
},
}
}
4 changes: 3 additions & 1 deletion pkg/controllers/edgeconnect/deployment/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,13 @@ func create(instance *edgeconnectv1alpha1.EdgeConnect) *appsv1.Deployment {
Spec: corev1.PodSpec{
Containers: []corev1.Container{edgeConnectContainer(instance)},
ImagePullSecrets: prepareImagePullSecrets(instance),
ServiceAccountName: consts.EdgeConnectServiceAccountName,
ServiceAccountName: instance.Spec.ServiceAccountName,
DeprecatedServiceAccount: instance.Spec.ServiceAccountName,
TerminationGracePeriodSeconds: address.Of(int64(30)),
Volumes: prepareVolumes(instance),
NodeSelector: instance.Spec.NodeSelector,
Tolerations: instance.Spec.Tolerations,
HostAliases: []corev1.HostAlias{},
TopologySpreadConstraints: instance.Spec.TopologySpreadConstraints,
},
},
Expand Down

0 comments on commit 2885871

Please sign in to comment.