Skip to content
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
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ fmt:
@echo ">> Ensuring style of files"
@go run golang.org/x/tools/cmd/goimports -w $(SOURCES)

.PHONY: license
license:
@echo ">> Ensuring license of files"
@go run github.com/google/addlicense -f "./tools/codegen/boilerplate.go.txt" $(SOURCES)

.PHONY: fmt-verify
fmt-verify: license-verify
@echo ">> Verify files style"
Expand Down
5 changes: 5 additions & 0 deletions chart/kube-arangodb/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ spec:
- --operator.backup
{{- end }}
- --chaos.allowed={{ .Values.operator.allowChaos }}
{{- if .Values.operator.args }}
{{- range .Values.operator.args }}
- {{ . | quote }}
{{- end }}
{{- end }}
env:
- name: MY_POD_NAMESPACE
valueFrom:
Expand Down
2 changes: 2 additions & 0 deletions chart/kube-arangodb/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ operator:
imagePullPolicy: IfNotPresent
imagePullSecrets: []

args: []

service:
type: ClusterIP

Expand Down
7 changes: 7 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import (
"strings"
"time"

"github.com/arangodb/kube-arangodb/pkg/deployment/features"

"github.com/rs/zerolog/log"

deploymentApi "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
Expand Down Expand Up @@ -105,6 +107,8 @@ var (
enableBackup bool // Run backup operator

alpineImage, metricsExporterImage, arangoImage string

singleMode bool
}
chaosOptions struct {
allowed bool
Expand Down Expand Up @@ -133,7 +137,9 @@ func init() {
f.StringVar(&operatorOptions.metricsExporterImage, "operator.metrics-exporter-image", MetricsExporterImageEnv.GetOrDefault(defaultMetricsExporterImage), "Docker image used for metrics containers by default")
f.StringVar(&operatorOptions.arangoImage, "operator.arango-image", ArangoImageEnv.GetOrDefault(defaultArangoImage), "Docker image used for arango by default")
f.BoolVar(&chaosOptions.allowed, "chaos.allowed", false, "Set to allow chaos in deployments. Only activated when allowed and enabled in deployment")
f.BoolVar(&operatorOptions.singleMode, "mode.single", false, "Enable single mode in Operator. WARNING: There should be only one replica of Operator, otherwise Operator can take unexpected actions")

features.Init(&cmdMain)
}

func main() {
Expand Down Expand Up @@ -300,6 +306,7 @@ func newOperatorConfigAndDeps(id, namespace, name string) (operator.Config, oper
AlpineImage: operatorOptions.alpineImage,
MetricsExporterImage: operatorOptions.metricsExporterImage,
ArangoImage: operatorOptions.arangoImage,
SingleMode: operatorOptions.singleMode,
}
deps := operator.Dependencies{
LogService: logService,
Expand Down
4 changes: 3 additions & 1 deletion pkg/deployment/context_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import (
"strconv"
"time"

"github.com/arangodb/kube-arangodb/pkg/deployment/features"

"github.com/arangodb/go-driver/http"
"github.com/arangodb/go-driver/jwt"
"github.com/arangodb/kube-arangodb/pkg/deployment/pod"
Expand Down Expand Up @@ -245,7 +247,7 @@ func (d *Deployment) getAuth() (driver.Authentication, error) {
secrets := d.GetKubeCli().CoreV1().Secrets(d.apiObject.GetNamespace())

var secret string
if i := d.apiObject.Status.CurrentImage; i == nil || i.ArangoDBVersion.CompareTo("3.7.0") < 0 || !i.Enterprise {
if i := d.apiObject.Status.CurrentImage; i == nil || !features.JWTRotation().Supported(i.ArangoDBVersion, i.Enterprise) {
s, err := secrets.Get(d.apiObject.Spec.Authentication.GetJWTSecretName(), meta.GetOptions{})
if err != nil {
return nil, goErrors.Errorf("JWT Secret is missing")
Expand Down
66 changes: 65 additions & 1 deletion pkg/deployment/deployment_encryption_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ func TestEnsurePod_ArangoDB_Encryption(t *testing.T) {
},
},
{
Name: "Agent EE 3.7.0 Pod with encrypted rocksdb",
Name: "Agent EE 3.7.0 Pod with encrypted rocksdb, disabled feature",
ArangoDeployment: &api.ArangoDeployment{
Spec: api.DeploymentSpec{
Image: util.NewString(testImage),
Expand All @@ -225,6 +225,70 @@ func TestEnsurePod_ArangoDB_Encryption(t *testing.T) {
k8sutil.CreateEncryptionKeySecret(secrets, testRocksDBEncryptionKey, key)
},
ExpectedEvent: "member agent is created",
ExpectedPod: core.Pod{
Spec: core.PodSpec{
Volumes: []core.Volume{
k8sutil.CreateVolumeEmptyDir(k8sutil.ArangodVolumeName),
k8sutil.CreateVolumeWithSecret(k8sutil.RocksdbEncryptionVolumeName, testRocksDBEncryptionKey),
},
Containers: []core.Container{
{
Name: k8sutil.ServerContainerName,
Image: testImage,
Command: BuildTestAgentArgs(t, firstAgentStatus.ID,
AgentArgsWithTLS(firstAgentStatus.ID, false),
ArgsWithAuth(false),
ArgsWithEncryptionKey()),
Ports: createTestPorts(),
VolumeMounts: []core.VolumeMount{
k8sutil.ArangodVolumeMount(),
k8sutil.RocksdbEncryptionVolumeMount(),
},
Resources: emptyResources,
LivenessProbe: createTestLivenessProbe(cmd, false, "", k8sutil.ArangoPort),
ImagePullPolicy: core.PullIfNotPresent,
SecurityContext: securityContext.NewSecurityContext(),
},
},
RestartPolicy: core.RestartPolicyNever,
TerminationGracePeriodSeconds: &defaultAgentTerminationTimeout,
Hostname: testDeploymentName + "-" + api.ServerGroupAgentsString + "-" + firstAgentStatus.ID,
Subdomain: testDeploymentName + "-int",
Affinity: k8sutil.CreateAffinity(testDeploymentName, api.ServerGroupAgentsString,
false, ""),
},
},
},
{
Name: "Agent EE 3.7.0 Pod with encrypted rocksdb, enabled feature",
ArangoDeployment: &api.ArangoDeployment{
Spec: api.DeploymentSpec{
Image: util.NewString(testImage),
Authentication: noAuthentication,
TLS: noTLS,
RocksDB: rocksDBSpec,
},
},
Features: testCaseFeatures{
EncryptionRotation: true,
},
Helper: func(t *testing.T, deployment *Deployment, testCase *testCaseStruct) {
deployment.status.last = api.DeploymentStatus{
Members: api.DeploymentStatusMembers{
Agents: api.MemberStatusList{
firstAgentStatus,
},
},
Images: createTestImagesWithVersion(true, "3.7.0"),
}

testCase.createTestPodData(deployment, api.ServerGroupAgents, firstAgentStatus)

secrets := deployment.GetKubeCli().CoreV1().Secrets(testNamespace)
key := make([]byte, 32)
k8sutil.CreateEncryptionKeySecret(secrets, testRocksDBEncryptionKey, key)
},
ExpectedEvent: "member agent is created",
ExpectedPod: core.Pod{
Spec: core.PodSpec{
Volumes: []core.Volume{
Expand Down
15 changes: 15 additions & 0 deletions pkg/deployment/deployment_pod_tls_sni_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ func TestEnsurePod_ArangoDB_TLS_SNI(t *testing.T) {
}(),
},
},
Features: testCaseFeatures{
TLSSNI: true,
},
Resources: func(t *testing.T, deployment *Deployment) {
createTLSSNISecret(t, deployment.GetKubeCli(), "sni1", deployment.Namespace(), constants.SecretTLSKeyfile, "")
createTLSSNISecret(t, deployment.GetKubeCli(), "sni2", deployment.Namespace(), constants.SecretTLSKeyfile, "")
Expand Down Expand Up @@ -155,6 +158,9 @@ func TestEnsurePod_ArangoDB_TLS_SNI(t *testing.T) {
}(),
},
},
Features: testCaseFeatures{
TLSSNI: true,
},
Resources: func(t *testing.T, deployment *Deployment) {
createTLSSNISecret(t, deployment.GetKubeCli(), "sni1", deployment.Namespace(), constants.SecretTLSKeyfile, "")
createTLSSNISecret(t, deployment.GetKubeCli(), "sni2", deployment.Namespace(), constants.SecretTLSKeyfile, "")
Expand Down Expand Up @@ -227,6 +233,9 @@ func TestEnsurePod_ArangoDB_TLS_SNI(t *testing.T) {
}(),
},
},
Features: testCaseFeatures{
TLSSNI: true,
},
Resources: func(t *testing.T, deployment *Deployment) {
createTLSSNISecret(t, deployment.GetKubeCli(), "sni1", deployment.Namespace(), constants.SecretTLSKeyfile, "")
createTLSSNISecret(t, deployment.GetKubeCli(), "sni2", deployment.Namespace(), constants.SecretTLSKeyfile, "")
Expand Down Expand Up @@ -299,6 +308,9 @@ func TestEnsurePod_ArangoDB_TLS_SNI(t *testing.T) {
}(),
},
},
Features: testCaseFeatures{
TLSSNI: true,
},
Resources: func(t *testing.T, deployment *Deployment) {
createTLSSNISecret(t, deployment.GetKubeCli(), "sni1", deployment.Namespace(), constants.SecretTLSKeyfile, "")
createTLSSNISecret(t, deployment.GetKubeCli(), "sni2", deployment.Namespace(), constants.SecretTLSKeyfile, "")
Expand Down Expand Up @@ -404,6 +416,9 @@ func TestEnsurePod_ArangoDB_TLS_SNI(t *testing.T) {
}(),
},
},
Features: testCaseFeatures{
TLSSNI: true,
},
Resources: func(t *testing.T, deployment *Deployment) {
createTLSSNISecret(t, deployment.GetKubeCli(), "sni1", deployment.Namespace(), constants.SecretTLSKeyfile, "")
createTLSSNISecret(t, deployment.GetKubeCli(), "sni2", deployment.Namespace(), constants.SecretTLSKeyfile, "")
Expand Down
11 changes: 11 additions & 0 deletions pkg/deployment/deployment_run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import (
"fmt"
"testing"

"github.com/arangodb/kube-arangodb/pkg/deployment/features"

"github.com/rs/zerolog/log"

"github.com/arangodb/kube-arangodb/pkg/deployment/resources/inspector"
Expand Down Expand Up @@ -92,6 +94,15 @@ func runTestCase(t *testing.T, testCase testCaseStruct) {
testCase.Resources(t, d)
}

// Set features
{
*features.EncryptionRotation().EnabledPointer() = testCase.Features.EncryptionRotation
require.Equal(t, testCase.Features.EncryptionRotation, *features.EncryptionRotation().EnabledPointer())
*features.JWTRotation().EnabledPointer() = testCase.Features.JWTRotation
*features.TLSSNI().EnabledPointer() = testCase.Features.TLSSNI
*features.TLSRotation().EnabledPointer() = testCase.Features.TLSRotation
}

// Act
cache, err := inspector.NewInspector(d.GetKubeCli(), d.GetNamespace())
require.NoError(t, err)
Expand Down
5 changes: 5 additions & 0 deletions pkg/deployment/deployment_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ const (
testYes = "yes"
)

type testCaseFeatures struct {
TLSSNI, TLSRotation, JWTRotation, EncryptionRotation bool
}

type testCaseStruct struct {
Name string
ArangoDeployment *api.ArangoDeployment
Expand All @@ -78,6 +82,7 @@ type testCaseStruct struct {
ExpectedError error
ExpectedEvent string
ExpectedPod core.Pod
Features testCaseFeatures
}

func createTestTLSVolume(serverGroupString, ID string) core.Volume {
Expand Down
37 changes: 37 additions & 0 deletions pkg/deployment/features/encryption.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// DISCLAIMER
//
// Copyright 2020 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 features

func init() {
registerFeature(encryptionRotation)
}

var encryptionRotation = &feature{
name: "encryption-rotation",
description: "Encryption Key rotation in runtime",
version: "3.7.0",
enterpriseRequired: true,
enabledByDefault: false,
}

func EncryptionRotation() Feature {
return encryptionRotation
}
74 changes: 74 additions & 0 deletions pkg/deployment/features/features.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// DISCLAIMER
//
// Copyright 2020 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 features

import "github.com/arangodb/go-driver"

var _ Feature = &feature{}

type Feature interface {
Name() string
Description() string
Version() driver.Version
EnterpriseRequired() bool
EnabledByDefault() bool
Enabled() bool
EnabledPointer() *bool
Supported(v driver.Version, enterprise bool) bool
}

type feature struct {
name, description string
version driver.Version
enterpriseRequired, enabledByDefault, enabled bool
}

func (f feature) Supported(v driver.Version, enterprise bool) bool {
return Supported(&f, v, enterprise)
}

func (f feature) Enabled() bool {
return f.enabled
}

func (f *feature) EnabledPointer() *bool {
return &f.enabled
}

func (f feature) Version() driver.Version {
return f.version
}

func (f feature) EnterpriseRequired() bool {
return f.enterpriseRequired
}

func (f feature) EnabledByDefault() bool {
return f.enabledByDefault
}

func (f feature) Name() string {
return f.name
}

func (f feature) Description() string {
return f.description
}
Loading