Skip to content

Commit 23b0283

Browse files
authored
Merge pull request #243 from arangodb/bugfix/reject-critical-args
Reject critical options during validation fixes #207
2 parents d560463 + 4ce8541 commit 23b0283

File tree

4 files changed

+139
-0
lines changed

4 files changed

+139
-0
lines changed

pkg/apis/deployment/v1alpha/server_group_spec.go

+17
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,15 @@
2323
package v1alpha
2424

2525
import (
26+
"strings"
27+
2628
"github.com/pkg/errors"
2729
"k8s.io/api/core/v1"
2830
"k8s.io/apimachinery/pkg/api/resource"
2931

3032
"github.com/arangodb/kube-arangodb/pkg/util"
33+
arangod_options "github.com/arangodb/kube-arangodb/pkg/util/arangod/options"
34+
arangosync_options "github.com/arangodb/kube-arangodb/pkg/util/arangosync/options"
3135
"github.com/arangodb/kube-arangodb/pkg/util/k8sutil"
3236
)
3337

@@ -115,6 +119,19 @@ func (s ServerGroupSpec) Validate(group ServerGroup, used bool, mode DeploymentM
115119
return maskAny(errors.Wrapf(ValidationError, "Invalid storageClassName: %s", err))
116120
}
117121
}
122+
for _, arg := range s.Args {
123+
parts := strings.Split(arg, "=")
124+
optionKey := strings.TrimSpace(parts[0])
125+
if group.IsArangod() {
126+
if arangod_options.IsCriticalOption(optionKey) {
127+
return maskAny(errors.Wrapf(ValidationError, "Critical option '%s' cannot be overriden", optionKey))
128+
}
129+
} else if group.IsArangosync() {
130+
if arangosync_options.IsCriticalOption(optionKey) {
131+
return maskAny(errors.Wrapf(ValidationError, "Critical option '%s' cannot be overriden", optionKey))
132+
}
133+
}
134+
}
118135
} else if s.GetCount() != 0 {
119136
return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d for un-used group. Expected 0", s.GetCount()))
120137
}

pkg/apis/deployment/v1alpha/server_group_spec_test.go

+13
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,16 @@ func TestServerGroupSpecDefault(t *testing.T) {
107107
assert.Equal(t, "", def(ServerGroupSpec{}, g, true, DeploymentModeSingle).GetStorageClassName())
108108
}
109109
}
110+
111+
func TestServerGroupSpecValidateArgs(t *testing.T) {
112+
// Valid
113+
assert.Nil(t, ServerGroupSpec{Count: util.NewInt(1), Args: []string{}}.Validate(ServerGroupSingle, true, DeploymentModeSingle, EnvironmentDevelopment))
114+
assert.Nil(t, ServerGroupSpec{Count: util.NewInt(1), Args: []string{"--master.endpoint"}}.Validate(ServerGroupSingle, true, DeploymentModeSingle, EnvironmentDevelopment))
115+
assert.Nil(t, ServerGroupSpec{Count: util.NewInt(1), Args: []string{}}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentDevelopment))
116+
assert.Nil(t, ServerGroupSpec{Count: util.NewInt(1), Args: []string{"--server.authentication=true"}}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentDevelopment))
117+
// Invalid
118+
assert.Error(t, ServerGroupSpec{Count: util.NewInt(1), Args: []string{"--server.authentication=true"}}.Validate(ServerGroupSingle, true, DeploymentModeSingle, EnvironmentDevelopment))
119+
assert.Error(t, ServerGroupSpec{Count: util.NewInt(1), Args: []string{"--server.authentication", "true"}}.Validate(ServerGroupSingle, true, DeploymentModeSingle, EnvironmentDevelopment))
120+
assert.Error(t, ServerGroupSpec{Count: util.NewInt(1), Args: []string{"--master.endpoint=http://something"}}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentDevelopment))
121+
assert.Error(t, ServerGroupSpec{Count: util.NewInt(1), Args: []string{"--mq.type=strange"}}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentDevelopment))
122+
}

pkg/util/arangod/options/options.go

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2018 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 options
24+
25+
import "strings"
26+
27+
var (
28+
criticalOptionKeys = map[string]struct{}{
29+
"agency.activate": struct{}{},
30+
"agency.disaster-recovery-id": struct{}{},
31+
"agency.endpoint": struct{}{},
32+
"agency.my-address": struct{}{},
33+
"agency.size": struct{}{},
34+
"agency.supervision": struct{}{},
35+
"cluster.agency-endpoint": struct{}{},
36+
"cluster.my-address": struct{}{},
37+
"cluster.my-role": struct{}{},
38+
"database.directory": struct{}{},
39+
"database.auto-upgrade": struct{}{},
40+
"foxx.queues": struct{}{},
41+
"replication.automatic-failover": struct{}{},
42+
"rocksdb.encryption-keyfile": struct{}{},
43+
"server.authentication": struct{}{},
44+
"server.endpoint": struct{}{},
45+
"server.jwt-secret": struct{}{},
46+
"server.storage-engine": struct{}{},
47+
"ssl.keyfile": struct{}{},
48+
"ssl.ecdh-curve": struct{}{},
49+
}
50+
)
51+
52+
// IsCriticalOption returns true if the given string is the key of
53+
// an option of arangod that cannot be overwritten.
54+
func IsCriticalOption(optionKey string) bool {
55+
if strings.HasPrefix(optionKey, "--") {
56+
optionKey = optionKey[2:]
57+
}
58+
_, found := criticalOptionKeys[optionKey]
59+
return found
60+
}
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2018 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 options
24+
25+
import "strings"
26+
27+
var (
28+
criticalOptionKeys = map[string]struct{}{
29+
"cluster.jwt-secret": struct{}{},
30+
"cluster.endpoint": struct{}{},
31+
"master.endpoint": struct{}{},
32+
"master.jwt-secret": struct{}{},
33+
"mq.type": struct{}{},
34+
"server.client-cafile": struct{}{},
35+
"server.endpoint": struct{}{},
36+
"server.keyfile": struct{}{},
37+
"server.port": struct{}{},
38+
}
39+
)
40+
41+
// IsCriticalOption returns true if the given string is the key of
42+
// an option of arangosync that cannot be overwritten.
43+
func IsCriticalOption(optionKey string) bool {
44+
if strings.HasPrefix(optionKey, "--") {
45+
optionKey = optionKey[2:]
46+
}
47+
_, found := criticalOptionKeys[optionKey]
48+
return found
49+
}

0 commit comments

Comments
 (0)