Skip to content

Commit 11bfccd

Browse files
authored
[Feature] Add TLS SNI (#556)
1 parent ad76584 commit 11bfccd

38 files changed

+1875
-285
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ require (
4545
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 // indirect
4646
github.com/ugorji/go/codec v0.0.0-20181209151446-772ced7fd4c2 // indirect
4747
github.com/voxelbrain/goptions v0.0.0-20180630082107-58cddc247ea2 // indirect
48+
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b
4849
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a // indirect
4950
golang.org/x/sys v0.0.0-20200116001909-b77594299b42
5051
golang.org/x/tools v0.0.0-20200331202046-9d5940d49312 // indirect

pkg/apis/deployment/v1/plan.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ const (
6161
ActionTypeRenewTLSCertificate ActionType = "RenewTLSCertificate"
6262
// ActionTypeRenewTLSCACertificate causes the TLS CA certificate of the entire deployment to be renewed.
6363
ActionTypeRenewTLSCACertificate ActionType = "RenewTLSCACertificate"
64+
// ActionTypeUpdateTLSSNI update SNI inplace.
65+
ActionTypeUpdateTLSSNI ActionType = "UpdateTLSSNI"
6466
// ActionTypeSetCurrentImage causes status.CurrentImage to be updated to the image given in the action.
6567
ActionTypeSetCurrentImage ActionType = "SetCurrentImage"
6668
// ActionTypeDisableClusterScaling turns off scaling DBservers and coordinators
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2020 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
// Author Ewout Prangsma
21+
//
22+
23+
package v1
24+
25+
import (
26+
shared "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1"
27+
"github.com/pkg/errors"
28+
)
29+
30+
type TLSSNIRotateMode string
31+
32+
func (t *TLSSNIRotateMode) Get() TLSSNIRotateMode {
33+
if t == nil {
34+
return TLSSNIRotateModeInPlace
35+
}
36+
37+
return *t
38+
}
39+
40+
const (
41+
TLSSNIRotateModeInPlace TLSSNIRotateMode = "inplace"
42+
TLSSNIRotateModeRecreate TLSSNIRotateMode = "recreate"
43+
)
44+
45+
// TLSSNISpec holds TLS SNI additional certificates
46+
type TLSSNISpec struct {
47+
Mapping map[string][]string `json:"sniMapping,omitempty"`
48+
Mode *TLSSNIRotateMode `json:"mode,omitempty"`
49+
}
50+
51+
func (s TLSSNISpec) Validate() error {
52+
mapped := map[string]interface{}{}
53+
54+
for key, values := range s.Mapping {
55+
if err := shared.IsValidName(key); err != nil {
56+
return err
57+
}
58+
59+
for _, value := range values {
60+
if _, exists := mapped[value]; exists {
61+
return errors.Errorf("sni for host %s is already defined", value)
62+
}
63+
64+
// Mark value as existing
65+
mapped[value] = nil
66+
67+
if err := shared.IsValidDomain(value); err != nil {
68+
return err
69+
}
70+
}
71+
}
72+
73+
return nil
74+
}
75+
76+
// SetDefaultsFrom fills unspecified fields with a value from given source spec.
77+
func (s *TLSSNISpec) SetDefaultsFrom(source *TLSSNISpec) {
78+
if source == nil {
79+
return
80+
}
81+
}

pkg/apis/deployment/v1/tls_spec.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,10 @@ const (
3737

3838
// TLSSpec holds TLS specific configuration settings
3939
type TLSSpec struct {
40-
CASecretName *string `json:"caSecretName,omitempty"`
41-
AltNames []string `json:"altNames,omitempty"`
42-
TTL *Duration `json:"ttl,omitempty"`
40+
CASecretName *string `json:"caSecretName,omitempty"`
41+
AltNames []string `json:"altNames,omitempty"`
42+
TTL *Duration `json:"ttl,omitempty"`
43+
SNI *TLSSNISpec `json:",inline"`
4344
}
4445

4546
const (
@@ -57,6 +58,14 @@ func (s TLSSpec) GetAltNames() []string {
5758
return s.AltNames
5859
}
5960

61+
func (s TLSSpec) GetTLSSNISpec() TLSSNISpec {
62+
if s.SNI == nil {
63+
return TLSSNISpec{}
64+
}
65+
66+
return *s.SNI
67+
}
68+
6069
// GetTTL returns the value of ttl.
6170
func (s TLSSpec) GetTTL() Duration {
6271
return DurationOrDefault(s.TTL)
@@ -125,4 +134,6 @@ func (s *TLSSpec) SetDefaultsFrom(source TLSSpec) {
125134
if s.TTL == nil {
126135
s.TTL = NewDurationOrNil(source.TTL)
127136
}
137+
138+
s.SNI.SetDefaultsFrom(source.SNI)
128139
}

pkg/apis/deployment/v1/zz_generated.deepcopy.go

Lines changed: 41 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/apis/shared/v1/resource.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,11 @@ func IsValidName(name string) error {
110110

111111
return nil
112112
}
113+
114+
func IsValidDomain(name string) error {
115+
if res := validation.IsDNS1123Subdomain(name); len(res) > 0 {
116+
return errors.Errorf("validation of domain failed: %s", strings.Join(res, ", "))
117+
}
118+
119+
return nil
120+
}

pkg/deployment/context_impl.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func (d *Deployment) GetAlpineImage() string {
7676
return d.config.AlpineImage
7777
}
7878

79-
// GetNamespace returns the kubernetes namespace that contains
79+
// GetNamespSecretsInterfaceace returns the kubernetes namespace that contains
8080
// this deployment.
8181
func (d *Deployment) GetNamespace() string {
8282
return d.apiObject.GetNamespace()
@@ -438,12 +438,6 @@ func (d *Deployment) DeleteSecret(secretName string) error {
438438
return nil
439439
}
440440

441-
// GetExpectedPodArguments creates command line arguments for a server in the given group with given ID.
442-
func (d *Deployment) GetExpectedPodArguments(apiObject metav1.Object, deplSpec api.DeploymentSpec, group api.ServerGroup,
443-
agents api.MemberStatusList, id string, version driver.Version) []string {
444-
return d.resources.GetExpectedPodArguments(apiObject, deplSpec, group, agents, id, version)
445-
}
446-
447441
// GetShardSyncStatus returns true if all shards are in sync
448442
func (d *Deployment) GetShardSyncStatus() bool {
449443
return d.resources.GetShardSyncStatus()
@@ -506,3 +500,7 @@ func (d *Deployment) WithStatusUpdate(action func(s *api.DeploymentStatus) bool,
506500

507501
return d.updateStatus(status, version, force...)
508502
}
503+
504+
func (d *Deployment) SecretsInterface() k8sutil.SecretInterface {
505+
return d.GetKubeCli().CoreV1().Secrets(d.GetNamespace())
506+
}

pkg/deployment/deployment_core_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,8 +1240,6 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) {
12401240

12411241
testCase.ExpectedPod.Spec.Containers[0].LivenessProbe = createTestLivenessProbe(true,
12421242
authorization, k8sutil.ArangoPort)
1243-
testCase.ExpectedPod.Spec.Containers[1].VolumeMounts = append(
1244-
testCase.ExpectedPod.Spec.Containers[1].VolumeMounts, k8sutil.TlsKeyfileVolumeMount())
12451243
},
12461244
config: Config{
12471245
LifecycleImage: testImageLifecycle,
@@ -1287,7 +1285,11 @@ func TestEnsurePod_ArangoDB_Core(t *testing.T) {
12871285
},
12881286
Resources: emptyResources,
12891287
},
1290-
testCreateExporterContainer(true, emptyResources),
1288+
func() core.Container {
1289+
c := testCreateExporterContainer(true, emptyResources)
1290+
c.VolumeMounts = append(c.VolumeMounts, k8sutil.TlsKeyfileVolumeMount())
1291+
return c
1292+
}(),
12911293
},
12921294
RestartPolicy: core.RestartPolicyNever,
12931295
TerminationGracePeriodSeconds: &defaultDBServerTerminationTimeout,

pkg/deployment/deployment_inspector.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ func (d *Deployment) inspectDeploymentWithError(ctx context.Context, lastInterva
179179
}
180180

181181
// Create scale/update plan
182-
if err, updated := d.reconciler.CreatePlan(); err != nil {
182+
if err, updated := d.reconciler.CreatePlan(ctx); err != nil {
183183
return minInspectionInterval, errors.Wrapf(err, "Plan creation failed")
184184
} else if updated {
185185
return minInspectionInterval, nil

0 commit comments

Comments
 (0)