From 6f713a85e9f4719486dd73001bfff431c726acb1 Mon Sep 17 00:00:00 2001 From: Adam Janikowski <12255597+ajanikow@users.noreply.github.com> Date: Fri, 6 Dec 2024 12:16:20 +0100 Subject: [PATCH] [Feature] [Scheduler] Shutdown Integration (#1777) --- CHANGELOG.md | 1 + Dockerfile | 2 +- docs/integration-sidecar.md | 12 +++++ docs/integration/shutdown.v1.md | 32 +++++++++++++ integrations/envoy/auth/v3/response.go | 2 +- pkg/deployment/resources/arango_profiles.go | 1 + pkg/integrations/sidecar/integration.go | 23 +++++----- .../sidecar/integration.shutdown.v1.go | 11 +++++ .../sidecar/integration_interface.go | 45 +++++++++++++++++++ pkg/util/constants/profiles.go | 11 ++--- 10 files changed, 122 insertions(+), 18 deletions(-) create mode 100644 docs/integration/shutdown.v1.md create mode 100644 pkg/integrations/sidecar/integration_interface.go diff --git a/CHANGELOG.md b/CHANGELOG.md index efc7942b9..bc2f5d4e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ - (Improvement) Drop slash requirement from ArangoRoute - (Feature) (Networking) Pass through Server Header - (Feature) (Platform) Shutdown migration to CE +- (Feature) (Scheduler) Shutdown Integration ## [1.2.43](https://github.com/arangodb/kube-arangodb/tree/1.2.43) (2024-10-14) - (Feature) ArangoRoute CRD diff --git a/Dockerfile b/Dockerfile index 0c5d1c196..704847ef8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ ARG IMAGE=ubuntu:24.04 -ARG ENVOY_IMAGE=envoyproxy/envoy:v1.31.0 +ARG ENVOY_IMAGE=envoyproxy/envoy:v1.32.1 # Build Steps diff --git a/docs/integration-sidecar.md b/docs/integration-sidecar.md index a02658d3d..3cae93edb 100644 --- a/docs/integration-sidecar.md +++ b/docs/integration-sidecar.md @@ -87,6 +87,18 @@ metadata: integration.profiles.arangodb.com/storage: v2 ``` +#### [Shutdown V1](/docs/integration/shutdown.v1.md) + +Shutdown Integration Sidecar + +To enable: + +```yaml +metadata: + labels: + integration.profiles.arangodb.com/shutdown: v1 +``` + ### Envs #### INTEGRATION_API_ADDRESS diff --git a/docs/integration/shutdown.v1.md b/docs/integration/shutdown.v1.md new file mode 100644 index 000000000..6f953a9fb --- /dev/null +++ b/docs/integration/shutdown.v1.md @@ -0,0 +1,32 @@ +--- +layout: page +title: Authentication V1 +parent: ArangoDBPlatform +--- + +# Shutdown V1 + +Definitions: + +- [Service](../../integrations/shutdown/v1/definition/definition.proto) + +Operator will send shutdown request once all containers marked with annotation are stopped. + +Example: + +```yaml +metadata: + annotations: + core.shutdown.arangodb.com/app: "true" + core.shutdown.arangodb.com/app2: "true" + container.shutdown.arangodb.com/app3: port1 +spec: + containers: + - name: app + - name: app2 + - name: app3 + ports: + name: port1 +``` + +Pod will receive shutdown request on port `port1` if containers `app` and `app2` will be in non running state. diff --git a/integrations/envoy/auth/v3/response.go b/integrations/envoy/auth/v3/response.go index 15cc2499b..e65dc3959 100644 --- a/integrations/envoy/auth/v3/response.go +++ b/integrations/envoy/auth/v3/response.go @@ -66,7 +66,7 @@ func (d DeniedResponse) GetCheckResponse() (*pbEnvoyAuthV3.CheckResponse, error) resp.Body = string(z) resp.Headers = append(resp.Headers, &corev3.HeaderValueOption{ Header: &corev3.HeaderValue{ - Key: "content/type", + Key: "content-type", Value: "application/json", }, AppendAction: corev3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD, diff --git a/pkg/deployment/resources/arango_profiles.go b/pkg/deployment/resources/arango_profiles.go index 016428570..a533263fa 100644 --- a/pkg/deployment/resources/arango_profiles.go +++ b/pkg/deployment/resources/arango_profiles.go @@ -153,6 +153,7 @@ func (r *Resources) EnsureArangoProfiles(ctx context.Context, cachedStatus inspe Spec: spec, DeploymentName: apiObject.GetName(), })), + gen(constants.ProfilesIntegrationShutdown, constants.ProfilesIntegrationV1, always(sidecar.IntegrationShutdownV1{})), gen(constants.ProfilesIntegrationEnvoy, constants.ProfilesIntegrationV3, always(sidecar.IntegrationEnvoyV3{Spec: spec})), gen(constants.ProfilesIntegrationStorage, constants.ProfilesIntegrationV2, func() (sidecar.Integration, bool) { if v, err := cachedStatus.ArangoPlatformStorage().V1Alpha1(); err == nil { diff --git a/pkg/integrations/sidecar/integration.go b/pkg/integrations/sidecar/integration.go index ae19c66b0..c67666b8c 100644 --- a/pkg/integrations/sidecar/integration.go +++ b/pkg/integrations/sidecar/integration.go @@ -29,14 +29,6 @@ const ( ListenPortHealthName = "health" ) -type Integration interface { - Name() []string - Envs() ([]core.EnvVar, error) - GlobalEnvs() ([]core.EnvVar, error) - Volumes() ([]core.Volume, []core.VolumeMount, error) - Validate() error -} - func NewShutdownAnnotations(coreContainers []string) *schedulerApi.ProfileTemplate { pt := schedulerApi.ProfileTemplate{ Pod: &schedulerPodApi.Pod{ @@ -57,6 +49,7 @@ func NewIntegrationEnablement(integrations ...Integration) (*schedulerApi.Profil var envs, gEnvs []core.EnvVar var volumes []core.Volume var volumeMounts []core.VolumeMount + var annotations = map[string]string{} for _, integration := range integrations { name := strings.Join(integration.Name(), "/") @@ -72,6 +65,14 @@ func NewIntegrationEnablement(integrations ...Integration) (*schedulerApi.Profil volumeMounts = append(volumeMounts, lvolumeMounts...) } + if anns, err := getIntegrationAnnotations(integration); err != nil { + return nil, errors.Wrapf(err, "Failure in annotations %s", name) + } else { + for k, v := range anns { + annotations[k] = v + } + } + if lenvs, err := integration.Envs(); err != nil { return nil, errors.Wrapf(err, "Failure in envs %s", name) } else if len(lenvs) > 0 { @@ -92,6 +93,9 @@ func NewIntegrationEnablement(integrations ...Integration) (*schedulerApi.Profil return &schedulerApi.ProfileTemplate{ Priority: util.NewType(127), Pod: &schedulerPodApi.Pod{ + Metadata: &schedulerPodResourcesApi.Metadata{ + Annotations: annotations, + }, Volumes: &schedulerPodResourcesApi.Volumes{ Volumes: volumes, }, @@ -205,9 +209,6 @@ func NewIntegration(image *schedulerContainerResourcesApi.Image, integration *sc }, } - pt.Pod.Metadata.Annotations[fmt.Sprintf("%s/%s", constants.AnnotationShutdownContainer, ContainerName)] = ListenPortHealthName - pt.Pod.Metadata.Annotations[constants.AnnotationShutdownManagedContainer] = "true" - pt.Container.All.Environments = &schedulerContainerResourcesApi.Environments{ Env: envs, } diff --git a/pkg/integrations/sidecar/integration.shutdown.v1.go b/pkg/integrations/sidecar/integration.shutdown.v1.go index 824579a55..ee0be1561 100644 --- a/pkg/integrations/sidecar/integration.shutdown.v1.go +++ b/pkg/integrations/sidecar/integration.shutdown.v1.go @@ -21,13 +21,24 @@ package sidecar import ( + "fmt" + core "k8s.io/api/core/v1" + + "github.com/arangodb/kube-arangodb/pkg/util/constants" ) type IntegrationShutdownV1 struct { Core *Core } +func (i IntegrationShutdownV1) Annotations() (map[string]string, error) { + return map[string]string{ + fmt.Sprintf("%s/%s", constants.AnnotationShutdownContainer, ContainerName): ListenPortHealthName, + constants.AnnotationShutdownManagedContainer: "true", + }, nil +} + func (i IntegrationShutdownV1) Name() []string { return []string{"SHUTDOWN", "V1"} } diff --git a/pkg/integrations/sidecar/integration_interface.go b/pkg/integrations/sidecar/integration_interface.go new file mode 100644 index 000000000..3a341fa47 --- /dev/null +++ b/pkg/integrations/sidecar/integration_interface.go @@ -0,0 +1,45 @@ +// +// DISCLAIMER +// +// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package sidecar + +import core "k8s.io/api/core/v1" + +type Integration interface { + Name() []string + Envs() ([]core.EnvVar, error) + GlobalEnvs() ([]core.EnvVar, error) + Volumes() ([]core.Volume, []core.VolumeMount, error) + Validate() error +} + +type IntegrationAnnotations interface { + Integration + + Annotations() (map[string]string, error) +} + +func getIntegrationAnnotations(int Integration) (map[string]string, error) { + if v, ok := int.(IntegrationAnnotations); ok { + return v.Annotations() + } + + return nil, nil +} diff --git a/pkg/util/constants/profiles.go b/pkg/util/constants/profiles.go index 4126a505e..2669b47c6 100644 --- a/pkg/util/constants/profiles.go +++ b/pkg/util/constants/profiles.go @@ -28,11 +28,12 @@ const ProfilesDeployment = ProfileGroup + "/deployment" const ProfilesIntegrationPrefix = "integration." + ProfileGroup const ( - ProfilesIntegrationAuthn = "authn" - ProfilesIntegrationAuthz = "authz" - ProfilesIntegrationSched = "sched" - ProfilesIntegrationEnvoy = "envoy" - ProfilesIntegrationStorage = "storage" + ProfilesIntegrationAuthn = "authn" + ProfilesIntegrationAuthz = "authz" + ProfilesIntegrationSched = "sched" + ProfilesIntegrationEnvoy = "envoy" + ProfilesIntegrationStorage = "storage" + ProfilesIntegrationShutdown = "shutdown" ) const (