From d0ad82650fe6fd092bbc8a6557dcd0a22808da0d Mon Sep 17 00:00:00 2001 From: Tomasz Mielech Date: Tue, 9 Nov 2021 14:16:51 +0100 Subject: [PATCH 1/2] init pod creator with an error --- pkg/deployment/images.go | 6 +- pkg/deployment/resources/pod_creator.go | 86 +++++-------------- .../resources/pod_creator_arangod.go | 5 +- pkg/deployment/resources/pod_creator_sync.go | 49 ++++++++++- pkg/util/k8sutil/interfaces/pod_creator.go | 4 +- 5 files changed, 79 insertions(+), 71 deletions(-) diff --git a/pkg/deployment/images.go b/pkg/deployment/images.go index ee31f5937..9b85a2b12 100644 --- a/pkg/deployment/images.go +++ b/pkg/deployment/images.go @@ -225,7 +225,7 @@ func (ib *imagesBuilder) fetchArangoDBImageIDAndVersion(ctx context.Context, cac }, } - pod, err = resources.RenderArangoPod(cachedStatus, ib.APIObject, role, id, podName, &imagePod) + pod, err = resources.RenderArangoPod(ctx, cachedStatus, ib.APIObject, role, id, podName, &imagePod) if err != nil { log.Debug().Err(err).Msg("Failed to render image ID pod") return true, errors.WithStack(err) @@ -259,10 +259,12 @@ func (i *ImageUpdatePod) GetRole() string { return "id" } -func (i *ImageUpdatePod) Init(pod *core.Pod) { +func (i *ImageUpdatePod) Init(_ context.Context, _ interfaces.Inspector, pod *core.Pod) error { terminationGracePeriodSeconds := int64((time.Second * 30).Seconds()) pod.Spec.TerminationGracePeriodSeconds = &terminationGracePeriodSeconds pod.Spec.PriorityClassName = i.spec.ID.Get().PriorityClassName + + return nil } func (i *ImageUpdatePod) GetImagePullSecrets() []string { diff --git a/pkg/deployment/resources/pod_creator.go b/pkg/deployment/resources/pod_creator.go index d3243a995..40e6b0b86 100644 --- a/pkg/deployment/resources/pod_creator.go +++ b/pkg/deployment/resources/pod_creator.go @@ -348,7 +348,7 @@ func (r *Resources) RenderPodForMember(ctx context.Context, cachedStatus inspect // Prepare arguments autoUpgrade := newMember.Conditions.IsTrue(api.ConditionTypeAutoUpgrade) || spec.Upgrade.Get().AutoUpgrade - memberPod := MemberArangoDPod{ + podCreator = &MemberArangoDPod{ status: *newMember, groupSpec: groupSpec, spec: spec, @@ -361,11 +361,6 @@ func (r *Resources) RenderPodForMember(ctx context.Context, cachedStatus inspect arangoMember: *member, cachedStatus: cachedStatus, } - - if err := memberPod.Validate(cachedStatus); err != nil { - return nil, errors.WithStack(errors.Wrapf(err, "Validation of pods resources failed")) - } - podCreator = &memberPod } else if group.IsArangosync() { // Check image if !imageInfo.Enterprise { @@ -378,67 +373,21 @@ func (r *Resources) RenderPodForMember(ctx context.Context, cachedStatus inspect imageInfo.Image = spec.Sync.GetSyncImage() } - var tlsKeyfileSecretName, clientAuthCASecretName, masterJWTSecretName, clusterJWTSecretName string - // Check master JWT secret - - masterJWTSecretName = spec.Sync.Authentication.GetJWTSecretName() - err := k8sutil.RunWithTimeout(ctx, func(ctxChild context.Context) error { - return k8sutil.ValidateTokenSecret(ctxChild, cachedStatus.SecretReadInterface(), masterJWTSecretName) - }) - if err != nil { - return nil, errors.WithStack(errors.Wrapf(err, "Master JWT secret validation failed")) - } - - monitoringTokenSecretName := spec.Sync.Monitoring.GetTokenSecretName() - err = k8sutil.RunWithTimeout(ctx, func(ctxChild context.Context) error { - return k8sutil.ValidateTokenSecret(ctxChild, cachedStatus.SecretReadInterface(), monitoringTokenSecretName) - }) - if err != nil { - return nil, errors.WithStack(errors.Wrapf(err, "Monitoring token secret validation failed")) - } - - if group == api.ServerGroupSyncMasters { - // Create TLS secret - tlsKeyfileSecretName = k8sutil.CreateTLSKeyfileSecretName(apiObject.GetName(), role, newMember.ID) - // Check cluster JWT secret - if spec.IsAuthenticated() { - clusterJWTSecretName = spec.Authentication.GetJWTSecretName() - err = k8sutil.RunWithTimeout(ctx, func(ctxChild context.Context) error { - return k8sutil.ValidateTokenSecret(ctxChild, cachedStatus.SecretReadInterface(), clusterJWTSecretName) - }) - if err != nil { - return nil, errors.WithStack(errors.Wrapf(err, "Cluster JWT secret validation failed")) - } - } - // Check client-auth CA certificate secret - clientAuthCASecretName = spec.Sync.Authentication.GetClientCASecretName() - err = k8sutil.RunWithTimeout(ctx, func(ctxChild context.Context) error { - return k8sutil.ValidateCACertificateSecret(ctxChild, cachedStatus.SecretReadInterface(), clientAuthCASecretName) - }) - if err != nil { - return nil, errors.WithStack(errors.Wrapf(err, "Client authentication CA certificate secret validation failed")) - } - } - podCreator = &MemberSyncPod{ - tlsKeyfileSecretName: tlsKeyfileSecretName, - clientAuthCASecretName: clientAuthCASecretName, - masterJWTSecretName: masterJWTSecretName, - clusterJWTSecretName: clusterJWTSecretName, - groupSpec: groupSpec, - spec: spec, - group: group, - resources: r, - imageInfo: imageInfo, - arangoMember: *member, - apiObject: apiObject, - memberStatus: *newMember, + groupSpec: groupSpec, + spec: spec, + group: group, + resources: r, + imageInfo: imageInfo, + arangoMember: *member, + apiObject: apiObject, + memberStatus: *newMember, } } else { return nil, errors.Newf("unable to render Pod") } - pod, err := RenderArangoPod(cachedStatus, apiObject, role, newMember.ID, newMember.PodName, podCreator) + pod, err := RenderArangoPod(ctx, cachedStatus, apiObject, role, newMember.ID, newMember.PodName, podCreator) if err != nil { return nil, err } @@ -625,10 +574,15 @@ func (r *Resources) createPodForMember(ctx context.Context, cachedStatus inspect } // RenderArangoPod renders new ArangoD Pod -func RenderArangoPod(cachedStatus inspectorInterface.Inspector, deployment k8sutil.APIObject, role, id, podName string, - podCreator interfaces.PodCreator) (*core.Pod, error) { +func RenderArangoPod(ctx context.Context, cachedStatus inspectorInterface.Inspector, deployment k8sutil.APIObject, + role, id, podName string, podCreator interfaces.PodCreator) (*core.Pod, error) { - // Prepare basic pod + // Validate if the pod can be created. + if err := podCreator.Validate(cachedStatus); err != nil { + return nil, errors.Wrapf(err, "Validation of pods resources failed") + } + + // Prepare basic pod. p := k8sutil.NewPod(deployment.GetName(), role, id, podName, podCreator) for k, v := range podCreator.Annotations() { @@ -647,7 +601,9 @@ func RenderArangoPod(cachedStatus inspectorInterface.Inspector, deployment k8sut p.Labels[k] = v } - podCreator.Init(&p) + if err := podCreator.Init(ctx, cachedStatus, &p); err != nil { + return nil, errors.Wrapf(err, "failed to init the pod") + } if initContainers, err := podCreator.GetInitContainers(cachedStatus); err != nil { return nil, errors.WithStack(err) diff --git a/pkg/deployment/resources/pod_creator_arangod.go b/pkg/deployment/resources/pod_creator_arangod.go index e20f81ba2..fed294ff9 100644 --- a/pkg/deployment/resources/pod_creator_arangod.go +++ b/pkg/deployment/resources/pod_creator_arangod.go @@ -23,6 +23,7 @@ package resources import ( + "context" "fmt" "math" "os" @@ -252,10 +253,12 @@ func (m *MemberArangoDPod) AsInput() pod.Input { } } -func (m *MemberArangoDPod) Init(pod *core.Pod) { +func (m *MemberArangoDPod) Init(_ context.Context, _ interfaces.Inspector, pod *core.Pod) error { terminationGracePeriodSeconds := int64(math.Ceil(m.group.DefaultTerminationGracePeriod().Seconds())) pod.Spec.TerminationGracePeriodSeconds = &terminationGracePeriodSeconds pod.Spec.PriorityClassName = m.groupSpec.PriorityClassName + + return nil } func (m *MemberArangoDPod) Validate(cachedStatus interfaces.Inspector) error { diff --git a/pkg/deployment/resources/pod_creator_sync.go b/pkg/deployment/resources/pod_creator_sync.go index 8dbaf7b03..c9ccd39c7 100644 --- a/pkg/deployment/resources/pod_creator_sync.go +++ b/pkg/deployment/resources/pod_creator_sync.go @@ -23,8 +23,11 @@ package resources import ( + "context" "math" + "github.com/arangodb/kube-arangodb/pkg/util/errors" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/arangodb/kube-arangodb/pkg/util/collection" @@ -298,13 +301,55 @@ func (m *MemberSyncPod) GetContainerCreator() interfaces.ContainerCreator { } } -func (m *MemberSyncPod) Init(pod *core.Pod) { +// Init initializes the arangosync pod. +func (m *MemberSyncPod) Init(ctx context.Context, cachedStatus interfaces.Inspector, pod *core.Pod) error { terminationGracePeriodSeconds := int64(math.Ceil(m.group.DefaultTerminationGracePeriod().Seconds())) pod.Spec.TerminationGracePeriodSeconds = &terminationGracePeriodSeconds pod.Spec.PriorityClassName = m.groupSpec.PriorityClassName + + m.masterJWTSecretName = m.spec.Sync.Authentication.GetJWTSecretName() + err := k8sutil.RunWithTimeout(ctx, func(ctxChild context.Context) error { + return k8sutil.ValidateTokenSecret(ctxChild, cachedStatus.SecretReadInterface(), m.masterJWTSecretName) + }) + if err != nil { + return errors.Wrapf(err, "ArangoSync master JWT secret validation failed") + } + + monitoringTokenSecretName := m.spec.Sync.Monitoring.GetTokenSecretName() + err = k8sutil.RunWithTimeout(ctx, func(ctxChild context.Context) error { + return k8sutil.ValidateTokenSecret(ctxChild, cachedStatus.SecretReadInterface(), monitoringTokenSecretName) + }) + if err != nil { + return errors.Wrapf(err, "ArangoSync monitoring token secret validation failed") + } + + if m.group == api.ServerGroupSyncMasters { + // Create TLS secret + m.tlsKeyfileSecretName = k8sutil.CreateTLSKeyfileSecretName(m.apiObject.GetName(), m.group.AsRole(), m.memberStatus.ID) + // Check cluster JWT secret + if m.spec.IsAuthenticated() { + m.clusterJWTSecretName = m.spec.Authentication.GetJWTSecretName() + err = k8sutil.RunWithTimeout(ctx, func(ctxChild context.Context) error { + return k8sutil.ValidateTokenSecret(ctxChild, cachedStatus.SecretReadInterface(), m.clusterJWTSecretName) + }) + if err != nil { + return errors.Wrapf(err, "ArangoSync cluster JWT secret validation failed") + } + } + // Check client-auth CA certificate secret + m.clientAuthCASecretName = m.spec.Sync.Authentication.GetClientCASecretName() + err = k8sutil.RunWithTimeout(ctx, func(ctxChild context.Context) error { + return k8sutil.ValidateCACertificateSecret(ctxChild, cachedStatus.SecretReadInterface(), m.clientAuthCASecretName) + }) + if err != nil { + return errors.Wrapf(err, "ArangoSync client authentication CA certificate secret validation failed") + } + } + + return nil } -func (m *MemberSyncPod) Validate(cachedStatus interfaces.Inspector) error { +func (m *MemberSyncPod) Validate(_ interfaces.Inspector) error { return nil } diff --git a/pkg/util/k8sutil/interfaces/pod_creator.go b/pkg/util/k8sutil/interfaces/pod_creator.go index 1cd908071..a3486bdf5 100644 --- a/pkg/util/k8sutil/interfaces/pod_creator.go +++ b/pkg/util/k8sutil/interfaces/pod_creator.go @@ -23,6 +23,8 @@ package interfaces import ( + "context" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/secret" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/service" core "k8s.io/api/core/v1" @@ -38,7 +40,7 @@ type PodModifier interface { } type PodCreator interface { - Init(*core.Pod) + Init(context.Context, Inspector, *core.Pod) error GetName() string GetRole() string GetVolumes() []core.Volume From f87b6bbfcef04769a9ab1bf0e9d3ed55cbfb1451 Mon Sep 17 00:00:00 2001 From: Tomasz Mielech Date: Tue, 9 Nov 2021 14:29:56 +0100 Subject: [PATCH 2/2] fix unit tests --- pkg/deployment/resources/pod_creator.go | 2 +- pkg/deployment/resources/pod_creator_sync.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/deployment/resources/pod_creator.go b/pkg/deployment/resources/pod_creator.go index 40e6b0b86..695958c96 100644 --- a/pkg/deployment/resources/pod_creator.go +++ b/pkg/deployment/resources/pod_creator.go @@ -602,7 +602,7 @@ func RenderArangoPod(ctx context.Context, cachedStatus inspectorInterface.Inspec } if err := podCreator.Init(ctx, cachedStatus, &p); err != nil { - return nil, errors.Wrapf(err, "failed to init the pod") + return nil, err } if initContainers, err := podCreator.GetInitContainers(cachedStatus); err != nil { diff --git a/pkg/deployment/resources/pod_creator_sync.go b/pkg/deployment/resources/pod_creator_sync.go index c9ccd39c7..1a466441a 100644 --- a/pkg/deployment/resources/pod_creator_sync.go +++ b/pkg/deployment/resources/pod_creator_sync.go @@ -312,7 +312,7 @@ func (m *MemberSyncPod) Init(ctx context.Context, cachedStatus interfaces.Inspec return k8sutil.ValidateTokenSecret(ctxChild, cachedStatus.SecretReadInterface(), m.masterJWTSecretName) }) if err != nil { - return errors.Wrapf(err, "ArangoSync master JWT secret validation failed") + return errors.Wrapf(err, "Master JWT secret validation failed") } monitoringTokenSecretName := m.spec.Sync.Monitoring.GetTokenSecretName() @@ -320,7 +320,7 @@ func (m *MemberSyncPod) Init(ctx context.Context, cachedStatus interfaces.Inspec return k8sutil.ValidateTokenSecret(ctxChild, cachedStatus.SecretReadInterface(), monitoringTokenSecretName) }) if err != nil { - return errors.Wrapf(err, "ArangoSync monitoring token secret validation failed") + return errors.Wrapf(err, "Monitoring token secret validation failed") } if m.group == api.ServerGroupSyncMasters { @@ -333,7 +333,7 @@ func (m *MemberSyncPod) Init(ctx context.Context, cachedStatus interfaces.Inspec return k8sutil.ValidateTokenSecret(ctxChild, cachedStatus.SecretReadInterface(), m.clusterJWTSecretName) }) if err != nil { - return errors.Wrapf(err, "ArangoSync cluster JWT secret validation failed") + return errors.Wrapf(err, "Cluster JWT secret validation failed") } } // Check client-auth CA certificate secret @@ -342,7 +342,7 @@ func (m *MemberSyncPod) Init(ctx context.Context, cachedStatus interfaces.Inspec return k8sutil.ValidateCACertificateSecret(ctxChild, cachedStatus.SecretReadInterface(), m.clientAuthCASecretName) }) if err != nil { - return errors.Wrapf(err, "ArangoSync client authentication CA certificate secret validation failed") + return errors.Wrapf(err, "Client authentication CA certificate secret validation failed") } }