Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAS-9906 Gateway config loader #1703

Merged
merged 1 commit into from
Aug 26, 2024
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 @@ -12,6 +12,7 @@
- (Feature) Envoy AuthV3 Integration
- (Maintenance) Switch to ubuntu:24.04 base image
- (Feature) Gateway Group for ArangoDeployment
- (Feature) Gateway config loader

## [1.2.42](https://github.com/arangodb/kube-arangodb/tree/1.2.42) (2024-07-23)
- (Maintenance) Go 1.22.4 & Kubernetes 1.29.6 libraries
Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ require (
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/coreos/go-semver v0.3.1
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9
github.com/envoyproxy/go-control-plane v0.11.1
github.com/fsnotify/fsnotify v1.7.0
github.com/gin-gonic/gin v1.9.1
github.com/golang-jwt/jwt v3.2.2+incompatible
Expand Down Expand Up @@ -69,13 +70,12 @@ require (
sigs.k8s.io/yaml v1.4.0
)

require github.com/envoyproxy/go-control-plane v0.11.1

require (
github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect
Expand Down Expand Up @@ -131,6 +131,7 @@ require (
golang.org/x/term v0.18.0 // indirect
golang.org/x/tools v0.17.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
Expand Down
72 changes: 2 additions & 70 deletions go.sum

Large diffs are not rendered by default.

113 changes: 113 additions & 0 deletions pkg/deployment/resources/config_maps.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
//
// 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 resources

import (
"context"
"fmt"
"time"

core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/arangodb/kube-arangodb/pkg/deployment/features"
"github.com/arangodb/kube-arangodb/pkg/metrics"
"github.com/arangodb/kube-arangodb/pkg/util"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/kube-arangodb/pkg/util/globals"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector"
configMapsV1 "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/configmap/v1"
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil/kerrors"
)

var (
inspectedConfigMapsCounters = metrics.MustRegisterCounterVec(metricsComponent, "inspected_config_maps", "Number of ConfigMaps inspections per deployment", metrics.DeploymentName)
inspectConfigMapsDurationGauges = metrics.MustRegisterGaugeVec(metricsComponent, "inspect_config_maps_duration", "Amount of time taken by a single inspection of all ConfigMaps for a deployment (in sec)", metrics.DeploymentName)
)

// EnsureConfigMaps creates all ConfigMaps needed to run the given deployment
func (r *Resources) EnsureConfigMaps(ctx context.Context, cachedStatus inspectorInterface.Inspector) error {
start := time.Now()
spec := r.context.GetSpec()
configMaps := cachedStatus.ConfigMapsModInterface().V1()
apiObject := r.context.GetAPIObject()
deploymentName := apiObject.GetName()

defer metrics.SetDuration(inspectConfigMapsDurationGauges.WithLabelValues(deploymentName), start)
counterMetric := inspectedConfigMapsCounters.WithLabelValues(deploymentName)

reconcileRequired := k8sutil.NewReconcile(cachedStatus)

if features.Gateway().Enabled() && spec.IsGatewayEnabled() {
counterMetric.Inc()
if err := reconcileRequired.WithError(r.ensureGatewayConfig(ctx, cachedStatus, configMaps)); err != nil {
return errors.Section(err, "Gateway ConfigMap")
}
}
return reconcileRequired.Reconcile(ctx)
}

func (r *Resources) ensureGatewayConfig(ctx context.Context, cachedStatus inspectorInterface.Inspector, configMaps configMapsV1.ModInterface) error {
deploymentName := r.context.GetAPIObject().GetName()
configMapName := GetGatewayConfigMapName(deploymentName)

if _, exists := cachedStatus.ConfigMap().V1().GetSimple(configMapName); !exists {
// Find serving service (single/crdn)
spec := r.context.GetSpec()
svcServingName := fmt.Sprintf("%s-%s", deploymentName, spec.Mode.Get().ServingGroup().AsRole())

svc, svcExist := cachedStatus.Service().V1().GetSimple(svcServingName)
if !svcExist {
return errors.Errorf("Service %s not found", svcServingName)
}

gatewayCfgYaml, err := RenderGatewayConfigYAML(svc.Spec.ClusterIP)
if err != nil {
return errors.WithStack(errors.Wrapf(err, "Failed to render gateway config"))
}
cm := &core.ConfigMap{
ObjectMeta: meta.ObjectMeta{
Name: configMapName,
},
Data: map[string]string{
GatewayConfigFileName: string(gatewayCfgYaml),
GatewayConfigChecksumName: util.SHA256(gatewayCfgYaml),
},
}

owner := r.context.GetAPIObject().AsOwner()

err = globals.GetGlobalTimeouts().Kubernetes().RunWithTimeout(ctx, func(ctxChild context.Context) error {
return k8sutil.CreateConfigMap(ctxChild, configMaps, cm, &owner)
})
if kerrors.IsAlreadyExists(err) {
// CM added while we tried it also
return nil
} else if err != nil {
// Failed to create
return errors.WithStack(err)
}

return errors.Reconcile()
}
return nil
}
Loading